Initial revision

This commit is contained in:
David Rose 2000-10-10 18:47:40 +00:00
parent b2c8a4a204
commit 67a298793d
271 changed files with 29431 additions and 0 deletions

18
pandatool/Config.pp Normal file
View File

@ -0,0 +1,18 @@
//
// Config.pp
//
// This file defines certain configuration variables that are written
// into the various make scripts. It is processed by ppremake (along
// with the Sources.pp files in each of the various directories) to
// generate build scripts appropriate to each environment.
//
// There are not too many variables to declare at this level; most of
// them are defined in the DTOOL-specific Config.pp.
// Where should we find PANDA? This will come from the environment
// variable if it is set.
#if $[eq $[PANDA],]
#define PANDA /usr/local/panda
#endif

34
pandatool/Package.pp Normal file
View File

@ -0,0 +1,34 @@
//
// Package.pp
//
// This file defines certain configuration variables that are to be
// written into the various make scripts. It is processed by ppremake
// (along with the Sources.pp files in each of the various
// directories) to generate build scripts appropriate to each
// environment.
//
// This is the package-specific file, which should be at the top of
// every source hierarchy. It generally gets the ball rolling, and is
// responsible for explicitly including all of the relevent Config.pp
// files.
// What is the name and version of this source tree?
#if $[eq $[PACKAGE],]
#define PACKAGE pandatool
#define VERSION 0.80
#endif
// Pull in the package-level Config file. This contains a few
// configuration variables that the user might want to fine-tune.
#include $[THISDIRPREFIX]Config.pp
// Also get the PANDA Package file and everything that includes.
#if $[eq $[wildcard $[PANDA]],]
#error Directory defined by $PANDA not found! Are you attached properly?
#endif
#include $[PANDA]/Package.pp

10
pandatool/Sources.pp Normal file
View File

@ -0,0 +1,10 @@
// This is the toplevel directory. It contains configure.in and other
// stuff.
#define DIR_TYPE toplevel
#define SAMPLE_SOURCE_FILE src/pandatoolbase/pandatoolbase.cxx
#define REQUIRED_TREES dtool panda
#define EXTRA_DIST \
Config.Irix.pp Config.Linux.pp Config.Win32.pp Package.pp

4
pandatool/src/Sources.pp Normal file
View File

@ -0,0 +1,4 @@
// This is a group directory: a directory level above a number of
// source subdirectories.
#define DIR_TYPE group

View File

@ -0,0 +1,32 @@
#begin bin_target
#define TARGET bam-info
#define LOCAL_LIBS \
eggbase progbase config compiler
#define OTHER_LIBS \
loader:c egg:c sgraphutil:c sgattrib:c sgraph:c pnmimagetypes:c \
graph:c putil:c express:c panda:m interrogatedb:c dtool:m
#define UNIX_SYS_LIBS \
m
#define SOURCES \
bamInfo.cxx bamInfo.h
#define INSTALL_HEADERS \
#end bin_target
#begin bin_target
#define TARGET egg2bam
#define LOCAL_LIBS \
eggbase progbase config compiler
#define OTHER_LIBS \
loader:c egg2sg:c builder:c egg:c pnmimagetypes:c graph:c putil:c \
express:c panda:m interrogatedb:c dtool:m
#define UNIX_SYS_LIBS \
m
#define SOURCES \
eggToBam.cxx eggToBam.h
#end bin_target

View File

@ -0,0 +1,167 @@
// Filename: bamInfo.cxx
// Created by: drose (02Jul00)
//
////////////////////////////////////////////////////////////////////
#include "bamInfo.h"
#include <bamFile.h>
#include <node.h>
#include <renderRelation.h>
#include <vector>
////////////////////////////////////////////////////////////////////
// Function: BamInfo::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
BamInfo::
BamInfo() {
set_program_description
("This program scans one or more Bam files--Panda's Binary Animation "
"and Models native binary format--and describes their contents.");
clear_runlines();
add_runline("[opts] input.bam [input.bam ... ]");
_num_scene_graphs = 0;
}
////////////////////////////////////////////////////////////////////
// Function: BamInfo::run
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BamInfo::
run() {
bool okflag = true;
Filenames::const_iterator fi;
for (fi = _filenames.begin(); fi != _filenames.end(); ++fi) {
if (!get_info(*fi)) {
okflag = false;
}
}
if (_num_scene_graphs > 0) {
nout << "\rScene graph statistics:\n";
_analyzer.write(nout, 2);
}
nout << "\r";
if (!okflag) {
// Exit with an error if any of the files was unreadable.
exit(1);
}
}
////////////////////////////////////////////////////////////////////
// Function: BamInfo::handle_args
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
bool BamInfo::
handle_args(ProgramBase::Args &args) {
if (args.empty()) {
nout << "You must specify the Bam file(s) to read on the command line.\n";
return false;
}
ProgramBase::Args::const_iterator ai;
for (ai = args.begin(); ai != args.end(); ++ai) {
_filenames.push_back(*ai);
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: BamInfo::get_info
// Access: Private
// Description: Reads a single Bam file and displays its contents.
// Returns true if successful, false on error.
////////////////////////////////////////////////////////////////////
bool BamInfo::
get_info(const Filename &filename) {
BamFile bam_file;
if (!bam_file.open_read(filename)) {
nout << "Unable to read.\n";
return false;
}
nout << filename << " : Bam version " << bam_file.get_file_major_ver()
<< "." << bam_file.get_file_minor_ver() << "\n";
typedef vector<TypedWriteable *> Objects;
Objects objects;
TypedWriteable *object = bam_file.read_object();
while (object != (TypedWriteable *)NULL) {
objects.push_back(object);
object = bam_file.read_object();
}
bam_file.resolve();
bam_file.close();
if (objects.size() == 1 && objects[0]->is_of_type(Node::get_class_type())) {
describe_scene_graph(DCAST(Node, objects[0]));
} else {
for (int i = 0; i < (int)objects.size(); i++) {
describe_general_object(objects[i]);
}
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: BamInfo::describe_scene_graph
// Access: Private
// Description: Called for Bam files that contain a single scene
// graph and no other objects. This should describe
// that scene graph in some meaningful way.
////////////////////////////////////////////////////////////////////
void BamInfo::
describe_scene_graph(Node *node) {
// Parent the node to our own scene graph root, so we can (a)
// guarantee it won't accidentally be deleted before we're done, (b)
// easily determine the bounding volume of the scene, and (c) report
// statistics on all the bam file's scene graphs together when we've
// finished.
PT_Node root = new Node;
NodeRelation *arc = new RenderRelation(root, node);
_num_scene_graphs++;
int num_nodes = _analyzer._num_nodes;
_analyzer.add_node(node);
num_nodes = _analyzer._num_nodes - num_nodes;
nout << " " << num_nodes << " nodes, bounding volume is "
<< arc->get_bound() << "\n";
}
////////////////////////////////////////////////////////////////////
// Function: BamInfo::describe_general_object
// Access: Private
// Description: Called for Bam files that contain multiple objects
// which may or may not be scene graph nodes. This
// should describe each object in some meaningful way.
////////////////////////////////////////////////////////////////////
void BamInfo::
describe_general_object(TypedWriteable *object) {
nout << " " << object->get_type() << "\n";
}
int main(int argc, char *argv[]) {
BamInfo prog;
prog.parse_command_line(argc, argv);
prog.run();
return 0;
}

View File

@ -0,0 +1,45 @@
// Filename: bamInfo.h
// Created by: drose (02Jul00)
//
////////////////////////////////////////////////////////////////////
#ifndef BAMINFO_H
#define BAMINFO_H
#include <pandatoolbase.h>
#include <eggToSomething.h>
#include <filename.h>
#include <pt_Node.h>
#include <sceneGraphAnalyzer.h>
#include <vector>
class TypedWriteable;
////////////////////////////////////////////////////////////////////
// Class : BamInfo
// Description :
////////////////////////////////////////////////////////////////////
class BamInfo : public ProgramBase {
public:
BamInfo();
void run();
protected:
virtual bool handle_args(Args &args);
private:
bool get_info(const Filename &filename);
void describe_scene_graph(Node *node);
void describe_general_object(TypedWriteable *object);
typedef vector<Filename> Filenames;
Filenames _filenames;
int _num_scene_graphs;
SceneGraphAnalyzer _analyzer;
};
#endif

View File

@ -0,0 +1,74 @@
// Filename: eggToBam.cxx
// Created by: drose (28Jun00)
//
////////////////////////////////////////////////////////////////////
#include "eggToBam.h"
#include <bamFile.h>
#include <load_egg_file.h>
////////////////////////////////////////////////////////////////////
// Function: EggToBam::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggToBam::
EggToBam() :
EggToSomething("Bam", ".bam", true, false)
{
set_program_description
("This program reads Egg files and outputs Bam files, the binary format "
"suitable for direct loading of animation and models into Panda.");
redescribe_option
("cs",
"Specify the coordinate system of the resulting " + _format_name +
" file. This may be "
"one of 'y-up', 'z-up', 'y-up-left', or 'z-up-left'. The default "
"is z-up.");
}
////////////////////////////////////////////////////////////////////
// Function: EggToBam::run
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void EggToBam::
run() {
if (!_got_coordinate_system) {
// If the user didn't specify otherwise, ensure the coordinate
// system is Z-up.
_data.set_coordinate_system(CS_zup_right);
}
PT_NamedNode root = load_egg_data(_data);
if (root == (NamedNode *)NULL) {
nout << "Unable to build scene graph from egg file.\n";
exit(1);
}
// This should be guaranteed because we pass false to the
// constructor, above.
nassertv(has_output_filename());
nout << "Writing " << get_output_filename() << "\n";
BamFile bam_file;
if (!bam_file.open_write(get_output_filename())) {
nout << "Error in writing.\n";
exit(1);
}
if (!bam_file.write_object(root)) {
nout << "Error in writing.\n";
exit(1);
}
}
int main(int argc, char *argv[]) {
EggToBam prog;
prog.parse_command_line(argc, argv);
prog.run();
return 0;
}

View File

@ -0,0 +1,24 @@
// Filename: eggToBam.h
// Created by: drose (28Jun00)
//
////////////////////////////////////////////////////////////////////
#ifndef EGGTOBAM_H
#define EGGTOBAM_H
#include <pandatoolbase.h>
#include <eggToSomething.h>
////////////////////////////////////////////////////////////////////
// Class : EggToBam
// Description :
////////////////////////////////////////////////////////////////////
class EggToBam : public EggToSomething {
public:
EggToBam();
void run();
};
#endif

View File

@ -0,0 +1 @@
#define INSTALL_DATA pandatool.init

View File

@ -0,0 +1,3 @@
ATTACH panda
DOCSH if { \which gtkmm-config >& /dev/null } setenv HAVE_GTK yes
DOSH if which gtkmm-config >/dev/null 2>&1; then HAVE_GTK="yes"; export HAVE_GTK; fi

View File

@ -0,0 +1,19 @@
#begin lib_target
#define TARGET eggbase
#define LOCAL_LIBS \
progbase
#define OTHER_LIBS \
egg:c panda:m
#define SOURCES \
eggBase.cxx eggBase.h eggConverter.cxx eggConverter.h eggFilter.cxx \
eggFilter.h eggReader.cxx eggReader.h eggToSomething.cxx \
eggToSomething.h eggWriter.cxx eggWriter.h somethingToEgg.cxx \
somethingToEgg.h
#define INSTALL_HEADERS \
eggBase.h eggConverter.h eggFilter.h eggReader.h eggToSomething.h \
eggWriter.h somethingToEgg.h
#end lib_target

View File

@ -0,0 +1,93 @@
// Filename: eggBase.cxx
// Created by: drose (14Feb00)
//
////////////////////////////////////////////////////////////////////
#include "eggBase.h"
#include <eggComment.h>
////////////////////////////////////////////////////////////////////
// Function: EggBase::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggBase::
EggBase() {
add_option
("cs", "coordinate-system", 80,
"Specify the coordinate system to operate in. This may be one of "
"'y-up', 'z-up', 'y-up-left', or 'z-up-left'.",
&EggBase::dispatch_coordinate_system,
&_got_coordinate_system, &_coordinate_system);
}
////////////////////////////////////////////////////////////////////
// Function: EggBase::post_command_line
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
bool EggBase::
post_command_line() {
if (_got_coordinate_system) {
_data.set_coordinate_system(_coordinate_system);
}
return ProgramBase::post_command_line();
}
////////////////////////////////////////////////////////////////////
// Function: EggBase::append_command_comment
// Access: Protected
// Description: Inserts a comment into the beginning of the indicated
// egg file corresponding to the command line that
// invoked this program.
//
// Normally this function is called automatically when
// appropriate by EggWriter, and it's not necessary to
// call it explicitly.
////////////////////////////////////////////////////////////////////
void EggBase::
append_command_comment(EggData &data) {
string comment;
comment = _program_name;
Args::const_iterator ai;
for (ai = _program_args.begin(); ai != _program_args.end(); ++ai) {
const string &arg = (*ai);
// First, check to see if the string is shell-acceptable.
bool legal = true;
string::const_iterator si;
for (si = arg.begin(); legal && si != arg.end(); ++si) {
switch (*si) {
case ' ':
case '\n':
case '\t':
case '*':
case '?':
case '\\':
case '(':
case ')':
case '|':
case '&':
case '<':
case '>':
case '"':
case ';':
case '$':
legal = false;
}
}
if (legal) {
comment += " " + arg;
} else {
comment += " '" + arg + "'";
}
}
data.insert(_data.begin(), new EggComment("", comment));
}

View File

@ -0,0 +1,41 @@
// Filename: eggBase.h
// Created by: drose (14Feb00)
//
////////////////////////////////////////////////////////////////////
#ifndef EGGBASE_H
#define EGGBASE_H
#include <pandatoolbase.h>
#include <programBase.h>
#include <coordinateSystem.h>
#include <eggData.h>
////////////////////////////////////////////////////////////////////
// Class : EggBase
// Description : This specialization of ProgramBase is intended for
// programs that read and/or write a single egg file.
// (See EggMultiBase for programs that operate on
// multiple egg files at once.)
//
// This is just a base class; see EggReader, EggWriter,
// or EggFilter according to your particular I/O needs.
////////////////////////////////////////////////////////////////////
class EggBase : public ProgramBase {
public:
EggBase();
protected:
virtual bool post_command_line();
void append_command_comment(EggData &_data);
protected:
bool _got_coordinate_system;
CoordinateSystem _coordinate_system;
EggData _data;
};
#endif

View File

@ -0,0 +1,28 @@
// Filename: eggConverter.cxx
// Created by: drose (15Feb00)
//
////////////////////////////////////////////////////////////////////
#include "eggConverter.h"
////////////////////////////////////////////////////////////////////
// Function: EggConverter::Constructor
// Access: Public
// Description: The first parameter to the constructor should be the
// one-word name of the alien file format that is to be
// read or written, for instance "OpenFlight" or
// "Alias". It's just used in printing error messages
// and such. The second parameter is the preferred
// extension of files of this form, if any, with a
// leading dot.
////////////////////////////////////////////////////////////////////
EggConverter::
EggConverter(const string &format_name,
const string &preferred_extension,
bool allow_last_param,
bool allow_stdout) :
EggFilter(allow_last_param, allow_stdout),
_format_name(format_name),
_preferred_extension(preferred_extension)
{
}

View File

@ -0,0 +1,33 @@
// Filename: eggConverter.h
// Created by: drose (15Feb00)
//
////////////////////////////////////////////////////////////////////
#ifndef EGGCONVERTER_H
#define EGGCONVERTER_H
#include <pandatoolbase.h>
#include "eggFilter.h"
////////////////////////////////////////////////////////////////////
// Class : EggConverter
// Description : This is a general base class for programs that
// convert between egg files and some other format. See
// EggToSomething and SomethingToEgg.
////////////////////////////////////////////////////////////////////
class EggConverter : public EggFilter {
public:
EggConverter(const string &format_name,
const string &preferred_extension = string(),
bool allow_last_param = true,
bool allow_stdout = true);
protected:
string _format_name;
string _preferred_extension;
};
#endif

View File

@ -0,0 +1,56 @@
// Filename: eggFilter.cxx
// Created by: drose (14Feb00)
//
////////////////////////////////////////////////////////////////////
#include "eggFilter.h"
////////////////////////////////////////////////////////////////////
// Function: EggFilter::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggFilter::
EggFilter(bool allow_last_param, bool allow_stdout) :
EggWriter(allow_last_param, allow_stdout)
{
clear_runlines();
if (allow_last_param) {
add_runline("[opts] input.egg output.egg");
}
add_runline("[opts] -o output.egg input.egg");
if (allow_stdout) {
add_runline("[opts] input.egg >output.egg");
}
redescribe_option
("cs",
"Specify the coordinate system of the resulting egg file. This may be "
" one of 'y-up', 'z-up', 'y-up-left', or 'z-up-left'. The default "
"is the same coordinate system as the input egg file. If this is "
"different from the input egg file, a conversion will be performed.");
}
////////////////////////////////////////////////////////////////////
// Function: EggFilter::handle_args
// Access: Protected, Virtual
// Description: Does something with the additional arguments on the
// command line (after all the -options have been
// parsed). Returns true if the arguments are good,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool EggFilter::
handle_args(ProgramBase::Args &args) {
if (_allow_last_param && !_got_output_filename && args.size() > 1) {
_got_output_filename = true;
_output_filename = args.back();
args.pop_back();
if (!verify_output_file_safe()) {
return false;
}
}
return EggReader::handle_args(args);
}

View File

@ -0,0 +1,28 @@
// Filename: eggFilter.h
// Created by: drose (14Feb00)
//
////////////////////////////////////////////////////////////////////
#ifndef EGGFILTER_H
#define EGGFILTER_H
#include <pandatoolbase.h>
#include "eggReader.h"
#include "eggWriter.h"
////////////////////////////////////////////////////////////////////
// Class : EggFilter
// Description : This is the base class for a program that reads an
// egg file, operates on it, and writes another egg file
// out.
////////////////////////////////////////////////////////////////////
class EggFilter : public EggReader, public EggWriter {
public:
EggFilter(bool allow_last_param = false, bool allow_stdout = true);
virtual bool handle_args(Args &args);
};
#endif

View File

@ -0,0 +1,51 @@
// Filename: eggReader.cxx
// Created by: drose (14Feb00)
//
////////////////////////////////////////////////////////////////////
#include "eggReader.h"
////////////////////////////////////////////////////////////////////
// Function: EggReader::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggReader::
EggReader() {
clear_runlines();
add_runline("[opts] input.egg");
redescribe_option
("cs",
"Specify the coordinate system to operate in. This may be "
" one of 'y-up', 'z-up', 'y-up-left', or 'z-up-left'. The default "
"is the coordinate system of the input egg file.");
}
////////////////////////////////////////////////////////////////////
// Function: EggReader::handle_args
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
bool EggReader::
handle_args(ProgramBase::Args &args) {
if (args.empty()) {
nout << "You must specify the egg file(s) to read on the command line.\n";
return false;
}
// Any separate egg files that are listed on the command line will
// get implicitly loaded up into one big egg file.
Args::const_iterator ai;
for (ai = args.begin(); ai != args.end(); ++ai) {
if (!_data.read(*ai)) {
// Rather than returning false, we simply exit here, so the
// ProgramBase won't try to tell the user how to run the program
// just because we got a bad egg file.
exit(1);
}
}
return true;
}

View File

@ -0,0 +1,30 @@
// Filename: eggReader.h
// Created by: drose (14Feb00)
//
////////////////////////////////////////////////////////////////////
#ifndef EGGREADER_H
#define EGGREADER_H
#include <pandatoolbase.h>
#include "eggBase.h"
////////////////////////////////////////////////////////////////////
// Class : EggReader
// Description : This is the base class for a program that reads egg
// files, but doesn't write an egg file.
////////////////////////////////////////////////////////////////////
class EggReader : virtual public EggBase {
public:
EggReader();
protected:
virtual bool handle_args(Args &args);
};
#endif

View File

@ -0,0 +1,104 @@
// Filename: eggToSomething.cxx
// Created by: drose (15Feb00)
//
////////////////////////////////////////////////////////////////////
#include "eggToSomething.h"
////////////////////////////////////////////////////////////////////
// Function: EggToSomething::Constructor
// Access: Public
// Description: The first parameter to the constructor should be the
// one-word name of the file format that is to be read,
// for instance "OpenFlight" or "Alias". It's just used
// in printing error messages and such.
////////////////////////////////////////////////////////////////////
EggToSomething::
EggToSomething(const string &format_name,
const string &preferred_extension,
bool allow_last_param, bool allow_stdout) :
EggConverter(format_name, preferred_extension, allow_last_param,
allow_stdout)
{
clear_runlines();
if (_allow_last_param) {
add_runline("[opts] input.egg output" + _preferred_extension);
}
add_runline("[opts] -o output" + _preferred_extension + " input.egg");
if (_allow_stdout) {
add_runline("[opts] input.egg >output" + _preferred_extension);
}
string o_description;
if (_allow_stdout) {
if (_allow_last_param) {
o_description =
"Specify the filename to which the resulting " + format_name +
" file will be written. "
"If this option is omitted, the last parameter name is taken to be the "
"name of the output file, or standard output is used if there are no "
"other parameters.";
} else {
o_description =
"Specify the filename to which the resulting " + format_name +
" file will be written. "
"If this option is omitted, the " + format_name +
" file is written to standard output.";
}
} else {
if (_allow_last_param) {
o_description =
"Specify the filename to which the resulting " + format_name +
" file will be written. "
"If this option is omitted, the last parameter name is taken to be the "
"name of the output file.";
} else {
o_description =
"Specify the filename to which the resulting " + format_name +
" file will be written.";
}
}
redescribe_option("o", o_description);
redescribe_option
("cs",
"Specify the coordinate system of the resulting " + _format_name +
" file. This may be "
"one of 'y-up', 'z-up', 'y-up-left', or 'z-up-left'. The default "
"is the same coordinate system as the input egg file. If this is "
"different from the input egg file, a conversion will be performed.");
}
////////////////////////////////////////////////////////////////////
// Function: EggToSomething::handle_args
// Access: Protected, Virtual
// Description: Does something with the additional arguments on the
// command line (after all the -options have been
// parsed). Returns true if the arguments are good,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool EggToSomething::
handle_args(ProgramBase::Args &args) {
if (_allow_last_param && !_got_output_filename && args.size() > 1) {
_got_output_filename = true;
_output_filename = args.back();
args.pop_back();
if (!_preferred_extension.empty() &&
("." + _output_filename.get_extension()) != _preferred_extension) {
nout << "Output filename " << _output_filename
<< " does not end in " << _preferred_extension
<< ". If this is really what you intended, "
"use the -o output_file syntax.\n";
return false;
}
if (!verify_output_file_safe()) {
return false;
}
}
return EggConverter::handle_args(args);
}

View File

@ -0,0 +1,32 @@
// Filename: eggToSomething.h
// Created by: drose (15Feb00)
//
////////////////////////////////////////////////////////////////////
#ifndef EGGTOSOMETHING_H
#define EGGTOSOMETHING_H
#include <pandatoolbase.h>
#include "eggConverter.h"
////////////////////////////////////////////////////////////////////
// Class : EggToSomething
// Description : This is the general base class for a file-converter
// program that reads some model file format and
// generates an egg file.
////////////////////////////////////////////////////////////////////
class EggToSomething : public EggConverter {
public:
EggToSomething(const string &format_name,
const string &preferred_extension = string(),
bool allow_last_param = true,
bool allow_stdout = true);
protected:
virtual bool handle_args(Args &args);
};
#endif

View File

@ -0,0 +1,211 @@
// Filename: eggWriter.cxx
// Created by: drose (14Feb00)
//
////////////////////////////////////////////////////////////////////
#include "eggWriter.h"
////////////////////////////////////////////////////////////////////
// Function: EggWriter::Constructor
// Access: Public
// Description: Egg-writing type programs may specify their output
// file using either the last-filename convention, the
// -o convention, and/or implicitly writing the result
// to standard output. Not all interfaces are
// appropriate for all applications; some may be
// confusing or dangerous.
//
// The calling application should pass allow_last_param
// true to allow the user to specify the output filename
// as the last parameter on the command line (the most
// dangerous, but convenient, method), and allow_stdout
// true to allow the user to omit the output filename
// altogether and have the output implicitly go to
// standard output (not terribly dangerous, but
// inappropriate when writing binary file formats).
////////////////////////////////////////////////////////////////////
EggWriter::
EggWriter(bool allow_last_param, bool allow_stdout) {
_allow_last_param = allow_last_param;
_allow_stdout = allow_stdout;
clear_runlines();
if (_allow_last_param) {
add_runline("[opts] output.egg");
}
add_runline("[opts] -o output.egg");
if (_allow_stdout) {
add_runline("[opts] >output.egg");
}
string o_description;
if (_allow_stdout) {
if (_allow_last_param) {
o_description =
"Specify the filename to which the resulting egg file will be written. "
"If this option is omitted, the last parameter name is taken to be the "
"name of the output file, or standard output is used if there are no "
"other parameters.";
} else {
o_description =
"Specify the filename to which the resulting egg file will be written. "
"If this option is omitted, the egg file is written to standard output.";
}
} else {
if (_allow_last_param) {
o_description =
"Specify the filename to which the resulting egg file will be written. "
"If this option is omitted, the last parameter name is taken to be the "
"name of the output file.";
} else {
o_description =
"Specify the filename to which the resulting egg file will be written.";
}
}
add_option
("o", "filename", 50, o_description,
&EggWriter::dispatch_filename, &_got_output_filename, &_output_filename);
redescribe_option
("cs",
"Specify the coordinate system of the resulting egg file. This may be "
" one of 'y-up', 'z-up', 'y-up-left', or 'z-up-left'. The default is "
"y-up.");
_output_ptr = (ostream *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: EggWriter::get_output
// Access: Public
// Description: Returns an output stream that corresponds to the
// user's intended egg file output--either stdout, or
// the named output file.
////////////////////////////////////////////////////////////////////
ostream &EggWriter::
get_output() {
if (_output_ptr == (ostream *)NULL) {
if (!_got_output_filename) {
// No filename given; use standard output.
assert(_allow_stdout);
_output_ptr = &cout;
} else {
// Attempt to open the named file.
unlink(_output_filename.c_str());
_output_stream.open(_output_filename.c_str(), ios::out, 0666);
if (!_output_stream) {
nout << "Unable to write to " << _output_filename << "\n";
exit(1);
}
nout << "Writing " << _output_filename << "\n";
_output_ptr = &_output_stream;
}
}
return *_output_ptr;
}
////////////////////////////////////////////////////////////////////
// Function: EggWriter::has_output_filename
// Access: Public
// Description: Returns true if the user specified an output
// filename, false otherwise (e.g. the output file is
// implicitly stdout).
////////////////////////////////////////////////////////////////////
bool EggWriter::
has_output_filename() const {
return _got_output_filename;
}
////////////////////////////////////////////////////////////////////
// Function: EggWriter::get_output_filename
// Access: Public
// Description: If has_output_filename() returns true, this is the
// filename that the user specified. Otherwise, it
// returns the empty string.
////////////////////////////////////////////////////////////////////
Filename EggWriter::
get_output_filename() const {
if (_got_output_filename) {
return _output_filename;
}
return Filename();
}
////////////////////////////////////////////////////////////////////
// Function: EggWriter::handle_args
// Access: Protected, Virtual
// Description: Does something with the additional arguments on the
// command line (after all the -options have been
// parsed). Returns true if the arguments are good,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool EggWriter::
handle_args(ProgramBase::Args &args) {
if (_allow_last_param && !_got_output_filename && !args.empty()) {
_got_output_filename = true;
_output_filename = args.back();
args.pop_back();
if (!verify_output_file_safe()) {
return false;
}
}
if (!args.empty()) {
nout << "Unexpected arguments on command line:\n";
copy(args.begin(), args.end(), ostream_iterator<string>(nout, " "));
nout << "\r";
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: EggWriter::post_command_line
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
bool EggWriter::
post_command_line() {
if (!_allow_stdout && !_got_output_filename) {
nout << "You must specify the filename to write with -o.\n";
return false;
}
append_command_comment(_data);
return EggBase::post_command_line();
}
////////////////////////////////////////////////////////////////////
// Function: EggWriter::verify_output_file_safe
// Access: Protected
// Description: This is called when the output file is given as the
// last parameter on the command line. Since this is a
// fairly dangerous way to specify the output file (it's
// easy to accidentally overwrite an input file this
// way), the convention is to disallow this syntax if
// the output file already exists.
//
// This function will test if the output file exists,
// and issue a warning message if it does, returning
// false. If all is well, it will return true.
////////////////////////////////////////////////////////////////////
bool EggWriter::
verify_output_file_safe() const {
nassertr(_got_output_filename, false);
if (_output_filename.exists()) {
nout << "The output filename " << _output_filename << " already exists. "
"If you wish to overwrite it, you must use the -o option to specify "
"the output filename, instead of simply specifying it as the last "
"parameter.\n";
return false;
}
return true;
}

View File

@ -0,0 +1,49 @@
// Filename: eggWriter.h
// Created by: drose (14Feb00)
//
////////////////////////////////////////////////////////////////////
#ifndef EGGWRITER_H
#define EGGWRITER_H
#include <pandatoolbase.h>
#include "eggBase.h"
#include <filename.h>
#include <fstream.h>
////////////////////////////////////////////////////////////////////
// Class : EggWriter
// Description : This is the base class for a program that generates
// an egg file output, but doesn't read any for input.
////////////////////////////////////////////////////////////////////
class EggWriter : virtual public EggBase {
public:
EggWriter(bool allow_last_param = false, bool allow_stdout = true);
ostream &get_output();
bool has_output_filename() const;
Filename get_output_filename() const;
protected:
virtual bool handle_args(Args &args);
virtual bool post_command_line();
bool verify_output_file_safe() const;
protected:
bool _allow_last_param;
bool _allow_stdout;
bool _got_output_filename;
Filename _output_filename;
private:
ofstream _output_stream;
ostream *_output_ptr;
};
#endif

View File

@ -0,0 +1,86 @@
// Filename: somethingToEgg.cxx
// Created by: drose (15Feb00)
//
////////////////////////////////////////////////////////////////////
#include "somethingToEgg.h"
////////////////////////////////////////////////////////////////////
// Function: SomethingToEgg::Constructor
// Access: Public
// Description: The first parameter to the constructor should be the
// one-word name of the file format that is to be read,
// for instance "OpenFlight" or "Alias". It's just used
// in printing error messages and such.
////////////////////////////////////////////////////////////////////
SomethingToEgg::
SomethingToEgg(const string &format_name,
const string &preferred_extension,
bool allow_last_param, bool allow_stdout) :
EggConverter(format_name, preferred_extension, allow_last_param, allow_stdout)
{
clear_runlines();
if (_allow_last_param) {
add_runline("[opts] input" + _preferred_extension + " output.egg");
}
add_runline("[opts] -o output.egg input" + _preferred_extension);
if (_allow_stdout) {
add_runline("[opts] input" + _preferred_extension + " >output.egg");
}
redescribe_option
("cs",
"Specify the coordinate system of the resulting egg file. This may be "
" one of 'y-up', 'z-up', 'y-up-left', or 'z-up-left'. The default "
"is the same coordinate system as the input " + _format_name +
" file, if this can be determined.");
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEgg::handle_args
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool SomethingToEgg::
handle_args(Args &args) {
if (_allow_last_param && !_got_output_filename && args.size() > 1) {
_got_output_filename = true;
_output_filename = args.back();
args.pop_back();
if (!(_output_filename.get_extension() == "egg")) {
nout << "Output filename " << _output_filename
<< " does not end in .egg. If this is really what you intended, "
"use the -o output_file syntax.\n";
return false;
}
if (!verify_output_file_safe()) {
return false;
}
}
if (args.empty()) {
nout << "You must specify the " << _format_name
<< " file to read on the command line.\n";
return false;
}
if (args.size() != 1) {
nout << "You may only specify one " << _format_name
<< " file to read on the command line. "
<< "You specified: ";
copy(args.begin(), args.end(), ostream_iterator<string>(nout, " "));
nout << "\n";
return false;
}
_input_filename = args[0];
if (access(_input_filename.c_str(), R_OK) != 0) {
nout << "Cannot find input file " << _input_filename << "\n";
return false;
}
return true;
}

View File

@ -0,0 +1,34 @@
// Filename: somethingToEgg.h
// Created by: drose (15Feb00)
//
////////////////////////////////////////////////////////////////////
#ifndef SOMETHINGTOEGG_H
#define SOMETHINGTOEGG_H
#include <pandatoolbase.h>
#include "eggConverter.h"
////////////////////////////////////////////////////////////////////
// Class : SomethingToEgg
// Description : This is the general base class for a file-converter
// program that reads some model file format and
// generates an egg file.
////////////////////////////////////////////////////////////////////
class SomethingToEgg : public EggConverter {
public:
SomethingToEgg(const string &format_name,
const string &preferred_extension = string(),
bool allow_last_param = true,
bool allow_stdout = true);
protected:
virtual bool handle_args(Args &args);
Filename _input_filename;
};
#endif

View File

@ -0,0 +1,16 @@
#begin bin_target
#define TARGET egg-trans
#define LOCAL_LIBS \
eggbase progbase config compiler
#define OTHER_LIBS \
egg:c linmath:c putil:c express:c panda:m
#define UNIX_SYS_LIBS \
m
#define SOURCES \
eggTrans.cxx eggTrans.h
#define INSTALL_HEADERS \
#end bin_target

View File

@ -0,0 +1,37 @@
// Filename: eggTrans.cxx
// Created by: drose (14Feb00)
//
////////////////////////////////////////////////////////////////////
#include "eggTrans.h"
////////////////////////////////////////////////////////////////////
// Function: EggTrans::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggTrans::
EggTrans() {
set_program_description
("This program reads an egg file and writes an essentially equivalent "
"egg file to the standard output, or to the file specified with -o. "
"Some simple operations on the egg file are supported.");
}
////////////////////////////////////////////////////////////////////
// Function: EggTrans::run
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void EggTrans::
run() {
_data.write_egg(get_output());
}
int main(int argc, char *argv[]) {
EggTrans prog;
prog.parse_command_line(argc, argv);
prog.run();
return 0;
}

View File

@ -0,0 +1,27 @@
// Filename: eggTrans.h
// Created by: drose (14Feb00)
//
////////////////////////////////////////////////////////////////////
#ifndef EGGTRANS_H
#define EGGTRANS_H
#include <pandatoolbase.h>
#include <eggFilter.h>
////////////////////////////////////////////////////////////////////
// Class : EggTrans
// Description : A program to read an egg file and write an equivalent
// egg file, possibly performing some minor operations
// along the way.
////////////////////////////////////////////////////////////////////
class EggTrans : public EggFilter {
public:
EggTrans();
void run();
};
#endif

View File

@ -0,0 +1,60 @@
#begin lib_target
#define TARGET flt
#define LOCAL_LIBS \
compiler
#define OTHER_LIBS \
mathutil:c linmath:c putil:c express:c panda:m dtool:m
#define UNIX_SYS_LIBS \
m
#define SOURCES \
config_flt.cxx config_flt.h fltBead.cxx fltBead.h fltBeadID.cxx \
fltBeadID.h fltError.cxx fltError.h fltExternalReference.cxx \
fltExternalReference.h fltEyepoint.cxx fltEyepoint.h fltFace.I \
fltFace.cxx fltFace.h fltGroup.cxx fltGroup.h fltHeader.cxx \
fltHeader.h fltInstanceDefinition.cxx fltInstanceDefinition.h \
fltInstanceRef.cxx fltInstanceRef.h fltLOD.cxx fltLOD.h \
fltLightSourceDefinition.cxx fltLightSourceDefinition.h \
fltMaterial.cxx fltMaterial.h fltObject.cxx fltObject.h \
fltOpcode.cxx fltOpcode.h fltPackedColor.I fltPackedColor.cxx \
fltPackedColor.h fltRecord.I fltRecord.cxx fltRecord.h \
fltRecordReader.cxx fltRecordReader.h fltRecordWriter.cxx \
fltRecordWriter.h fltTexture.cxx fltTexture.h fltTrackplane.cxx \
fltTrackplane.h fltTransformGeneralMatrix.cxx \
fltTransformGeneralMatrix.h fltTransformPut.cxx fltTransformPut.h \
fltTransformRecord.cxx fltTransformRecord.h \
fltTransformRotateAboutEdge.cxx fltTransformRotateAboutEdge.h \
fltTransformRotateAboutPoint.cxx fltTransformRotateAboutPoint.h \
fltTransformRotateScale.cxx fltTransformRotateScale.h \
fltTransformScale.cxx fltTransformScale.h fltTransformTranslate.cxx \
fltTransformTranslate.h fltUnsupportedRecord.cxx \
fltUnsupportedRecord.h fltVertex.I fltVertex.cxx fltVertex.h \
fltVertexList.cxx fltVertexList.h
#define INSTALL_HEADERS \
fltBead.h fltBeadID.h fltError.h fltExternalReference.h \
fltEyepoint.h fltFace.I fltFace.h fltGroup.h fltHeader.h \
fltInstanceDefinition.h fltInstanceRef.h fltLOD.h \
fltLightSourceDefinition.h fltMaterial.h fltObject.h fltOpcode.h \
fltPackedColor.I fltPackedColor.h fltRecord.I fltRecord.h \
fltRecordReader.h fltRecordWriter.h fltTexture.h fltTrackplane.h \
fltTransformGeneralMatrix.h fltTransformPut.h fltTransformRecord.h \
fltTransformRotateAboutEdge.h fltTransformRotateAboutPoint.h \
fltTransformRotateScale.h fltTransformScale.h \
fltTransformTranslate.h fltUnsupportedRecord.h fltVertex.I \
fltVertex.h fltVertexList.h
#end lib_target
#begin test_bin_target
#define TARGET test_flt
#define LOCAL_LIBS \
flt
#define OTHER_LIBS \
pystub
#define SOURCES \
test_flt.cxx
#end test_bin_target

View File

@ -0,0 +1,63 @@
// Filename: config_flt.cxx
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#include "config_flt.h"
#include "fltRecord.h"
#include "fltBead.h"
#include "fltBeadID.h"
#include "fltGroup.h"
#include "fltObject.h"
#include "fltFace.h"
#include "fltVertexList.h"
#include "fltLOD.h"
#include "fltInstanceDefinition.h"
#include "fltInstanceRef.h"
#include "fltHeader.h"
#include "fltVertex.h"
#include "fltMaterial.h"
#include "fltTexture.h"
#include "fltLightSourceDefinition.h"
#include "fltUnsupportedRecord.h"
#include "fltTransformRecord.h"
#include "fltTransformGeneralMatrix.h"
#include "fltTransformPut.h"
#include "fltTransformRotateAboutEdge.h"
#include "fltTransformRotateAboutPoint.h"
#include "fltTransformScale.h"
#include "fltTransformTranslate.h"
#include "fltTransformRotateScale.h"
#include "fltExternalReference.h"
#include <dconfig.h>
Configure(config_flt);
ConfigureFn(config_flt) {
FltRecord::init_type();
FltBead::init_type();
FltBeadID::init_type();
FltGroup::init_type();
FltObject::init_type();
FltFace::init_type();
FltVertexList::init_type();
FltLOD::init_type();
FltInstanceDefinition::init_type();
FltInstanceRef::init_type();
FltHeader::init_type();
FltVertex::init_type();
FltMaterial::init_type();
FltTexture::init_type();
FltLightSourceDefinition::init_type();
FltUnsupportedRecord::init_type();
FltTransformRecord::init_type();
FltTransformGeneralMatrix::init_type();
FltTransformPut::init_type();
FltTransformRotateAboutEdge::init_type();
FltTransformRotateAboutPoint::init_type();
FltTransformScale::init_type();
FltTransformTranslate::init_type();
FltTransformRotateScale::init_type();
FltExternalReference::init_type();
}

View File

@ -0,0 +1,11 @@
// Filename: config_flt.h
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef CONFIG_FLT_H
#define CONFIG_FLT_H
// No configure variables.
#endif

View File

@ -0,0 +1,391 @@
// Filename: fltBead.cxx
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltBead.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
#include "fltTransformGeneralMatrix.h"
#include "fltTransformPut.h"
#include "fltTransformRotateAboutEdge.h"
#include "fltTransformRotateAboutPoint.h"
#include "fltTransformScale.h"
#include "fltTransformTranslate.h"
#include "fltTransformRotateScale.h"
TypeHandle FltBead::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltBead::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltBead::
FltBead(FltHeader *header) : FltRecord(header) {
_has_transform = false;
_transform = LMatrix4d::ident_mat();
_replicate_count = 0;
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::has_transform
// Access: Public
// Description: Returns true if the bead has been transformed, false
// otherwise. If this returns true, get_transform()
// will return the single-precision net transformation,
// and get_num_transform_steps() will return nonzero.
////////////////////////////////////////////////////////////////////
bool FltBead::
has_transform() const {
return _has_transform;
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::get_transform
// Access: Public
// Description: Returns the single-precision 4x4 matrix that
// represents the transform applied to this bead, or the
// identity matrix if the bead has not been transformed.
////////////////////////////////////////////////////////////////////
const LMatrix4d &FltBead::
get_transform() const {
return _has_transform ? _transform : LMatrix4d::ident_mat();
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::set_transform
// Access: Public
// Description: Replaces the transform matrix on this bead. This
// implicitly removes all of the transform steps added
// previously, and replaces them with a single 4x4
// general matrix transform step.
////////////////////////////////////////////////////////////////////
void FltBead::
set_transform(const LMatrix4d &mat) {
clear_transform();
FltTransformGeneralMatrix *step = new FltTransformGeneralMatrix(_header);
step->set_matrix(mat);
add_transform_step(step);
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::clear_transform
// Access: Public
// Description: Removes any transform matrix and all transform steps
// on this bead.
////////////////////////////////////////////////////////////////////
void FltBead::
clear_transform() {
_has_transform = false;
_transform = LMatrix4d::ident_mat();
_transform_steps.clear();
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::get_num_transform_steps
// Access: Public
// Description: Returns the number of individual steps that define
// the net transform on this bead as returned by
// set_transform(). Each step is a single
// transformation; the concatenation of all
// transformations will produce the matrix represented
// by set_transform().
////////////////////////////////////////////////////////////////////
int FltBead::
get_num_transform_steps() const {
return _transform_steps.size();
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::get_transform_step
// Access: Public
// Description: Returns the nth individual step that defines
// the net transform on this bead. See
// get_num_transform_steps().
////////////////////////////////////////////////////////////////////
FltTransformRecord *FltBead::
get_transform_step(int n) {
nassertr(n >= 0 && n < (int)_transform_steps.size(),
(FltTransformRecord *)NULL);
return _transform_steps[n];
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::add_transform_step
// Access: Public
// Description: Applies the indicated transform step to the net
// transformation applied to the bead.
////////////////////////////////////////////////////////////////////
void FltBead::
add_transform_step(FltTransformRecord *record) {
if (!_has_transform) {
_has_transform = true;
_transform = record->get_matrix();
} else {
_transform = record->get_matrix() * _transform;
}
_transform_steps.push_back(record);
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::get_replicate_count
// Access: Public
// Description: Returns the replicate count of this bead. If this is
// nonzero, it means that the bead is implicitly copied
// this number of additional times (for replicate_count
// + 1 total copies), applying the transform on this
// bead for each copy. In this case, the transform does
// *not* apply to the initial copy of the bead.
////////////////////////////////////////////////////////////////////
int FltBead::
get_replicate_count() const {
return _replicate_count;
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::set_replicate_count
// Access: Public
// Description: Changes the replicate count of this bead. If you are
// setting the replicate count to some nonzero number,
// you must also set a transform on the bead. See
// set_replicate_count().
////////////////////////////////////////////////////////////////////
void FltBead::
set_replicate_count(int count) {
_replicate_count = count;
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this bead based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltBead::
extract_record(FltRecordReader &reader) {
if (!FltRecord::extract_record(reader)) {
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::extract_ancillary
// Access: Protected, Virtual
// Description: Checks whether the given bead, which follows this
// bead sequentially in the file, is an ancillary record
// of this bead. If it is, extracts the relevant
// information and returns true; otherwise, leaves it
// alone and returns false.
////////////////////////////////////////////////////////////////////
bool FltBead::
extract_ancillary(FltRecordReader &reader) {
FltTransformRecord *step = (FltTransformRecord *)NULL;
switch (reader.get_opcode()) {
case FO_transform_matrix:
return extract_transform_matrix(reader);
case FO_general_matrix:
step = new FltTransformGeneralMatrix(_header);
break;
case FO_put:
step = new FltTransformPut(_header);
break;
case FO_rotate_about_edge:
step = new FltTransformRotateAboutEdge(_header);
break;
case FO_rotate_about_point:
step = new FltTransformRotateAboutPoint(_header);
break;
case FO_scale:
step = new FltTransformScale(_header);
break;
case FO_translate:
step = new FltTransformTranslate(_header);
break;
case FO_rotate_and_scale:
step = new FltTransformRotateScale(_header);
break;
case FO_replicate:
return extract_replicate_count(reader);
default:
return FltRecord::extract_ancillary(reader);
}
// A transform step.
nassertr(step != (FltTransformRecord *)NULL, false);
step->extract_record(reader);
_transform_steps.push_back(DCAST(FltTransformRecord, step));
/*
cerr << "Added transform step: " << step->get_type() << "\n";
cerr << "Net matrix is:\n";
_transform.write(cerr, 2);
cerr << "Step is:\n";
step->get_matrix().write(cerr, 2);
*/
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltBead::
build_record(FltRecordWriter &writer) const {
if (!FltRecord::build_record(writer)) {
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::write_ancillary
// Access: Protected, Virtual
// Description: Writes whatever ancillary records are required for
// this record. Returns FE_ok on success, or something
// else if there is some error.
////////////////////////////////////////////////////////////////////
FltError FltBead::
write_ancillary(FltRecordWriter &writer) const {
if (_has_transform) {
FltError result = write_transform(writer);
if (result != FE_ok) {
return result;
}
}
if (_replicate_count != 0) {
FltError result = write_replicate_count(writer);
if (result != FE_ok) {
return result;
}
}
return FltRecord::write_ancillary(writer);
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::extract_transform_matrix
// Access: Private
// Description: Reads a transform matrix ancillary bead. This
// defines the net transformation that has been applied
// to the bead, and precedes the set of individual
// transform steps that define how this net transform
// was computed.
////////////////////////////////////////////////////////////////////
bool FltBead::
extract_transform_matrix(FltRecordReader &reader) {
nassertr(reader.get_opcode() == FO_transform_matrix, false);
DatagramIterator &iterator = reader.get_iterator();
LMatrix4d matrix;
for (int r = 0; r < 4; r++) {
for (int c = 0; c < 4; c++) {
matrix(r, c) = iterator.get_be_float32();
}
}
nassertr(iterator.get_remaining_size() == 0, true);
_transform_steps.clear();
_has_transform = true;
_transform = matrix;
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::extract_replicate_count
// Access: Private
// Description: Reads a replicate count ancillary bead.
////////////////////////////////////////////////////////////////////
bool FltBead::
extract_replicate_count(FltRecordReader &reader) {
nassertr(reader.get_opcode() == FO_replicate, false);
DatagramIterator &iterator = reader.get_iterator();
_replicate_count = iterator.get_be_int16();
iterator.skip_bytes(2);
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::write_transform
// Access: Private
// Description: Writes out the transformation and all of its defining
// steps.
////////////////////////////////////////////////////////////////////
FltError FltBead::
write_transform(FltRecordWriter &writer) const {
// First, write out the initial transform indication.
writer.set_opcode(FO_transform_matrix);
Datagram &datagram = writer.update_datagram();
for (int r = 0; r < 4; r++) {
for (int c = 0; c < 4; c++) {
datagram.add_be_float32(_transform(r, c));
}
}
FltError result = writer.advance();
if (result != FE_ok) {
return result;
}
// Now, write out each of the steps of the transform.
Transforms::const_iterator ti;
for (ti = _transform_steps.begin(); ti != _transform_steps.end(); ++ti) {
if (!(*ti)->build_record(writer)) {
return FE_invalid_record;
}
FltError result = writer.advance();
if (result != FE_ok) {
return result;
}
}
return FE_ok;
}
////////////////////////////////////////////////////////////////////
// Function: FltBead::write_replicate_count
// Access: Private
// Description: Writes out the replicate count, if needed.
////////////////////////////////////////////////////////////////////
FltError FltBead::
write_replicate_count(FltRecordWriter &writer) const {
if (_replicate_count != 0) {
writer.set_opcode(FO_replicate);
Datagram &datagram = writer.update_datagram();
datagram.add_be_int16(_replicate_count);
datagram.pad_bytes(2);
FltError result = writer.advance();
if (result != FE_ok) {
return result;
}
}
return FE_ok;
}

View File

@ -0,0 +1,83 @@
// Filename: fltBead.h
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTBEAD_H
#define FLTBEAD_H
#include <pandatoolbase.h>
#include "fltRecord.h"
#include "fltTransformRecord.h"
#include <luse.h>
////////////////////////////////////////////////////////////////////
// Class : FltBead
// Description : A base class for any of a broad family of flt records
// that represent particular beads in the hierarchy.
// These are things like group beads and object beads,
// as opposed to things like push and pop or comment
// records.
////////////////////////////////////////////////////////////////////
class FltBead : public FltRecord {
public:
FltBead(FltHeader *header);
bool has_transform() const;
const LMatrix4d &get_transform() const;
void set_transform(const LMatrix4d &mat);
void clear_transform();
int get_num_transform_steps() const;
FltTransformRecord *get_transform_step(int n);
void add_transform_step(FltTransformRecord *record);
int get_replicate_count() const;
void set_replicate_count(int count);
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool extract_ancillary(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
virtual FltError write_ancillary(FltRecordWriter &writer) const;
private:
bool extract_transform_matrix(FltRecordReader &reader);
bool extract_replicate_count(FltRecordReader &reader);
FltError write_transform(FltRecordWriter &writer) const;
FltError write_replicate_count(FltRecordWriter &writer) const;
private:
bool _has_transform;
LMatrix4d _transform;
typedef vector<PT(FltTransformRecord)> Transforms;
Transforms _transform_steps;
int _replicate_count;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltRecord::init_type();
register_type(_type_handle, "FltBead",
FltRecord::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#endif

View File

@ -0,0 +1,110 @@
// Filename: fltBeadID.cxx
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltBeadID.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
TypeHandle FltBeadID::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltBeadID::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltBeadID::
FltBeadID(FltHeader *header) : FltBead(header) {
}
////////////////////////////////////////////////////////////////////
// Function: FltBeadID::output
// Access: Public
// Description: Writes a quick one-line description of the record, but
// not its children. This is a human-readable
// description, primarily for debugging; to write a flt
// file, use FltHeader::write_flt().
////////////////////////////////////////////////////////////////////
void FltBeadID::
output(ostream &out) const {
out << get_type();
if (!_id.empty()) {
out << " " << _id;
}
}
////////////////////////////////////////////////////////////////////
// Function: FltBeadID::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this bead based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltBeadID::
extract_record(FltRecordReader &reader) {
if (!FltBead::extract_record(reader)) {
return false;
}
_id = reader.get_iterator().get_fixed_string(8);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltBeadID::extract_ancillary
// Access: Protected, Virtual
// Description: Checks whether the given bead, which follows this
// bead sequentially in the file, is an ancillary record
// of this bead. If it is, extracts the relevant
// information and returns true; otherwise, leaves it
// alone and returns false.
////////////////////////////////////////////////////////////////////
bool FltBeadID::
extract_ancillary(FltRecordReader &reader) {
if (reader.get_opcode() == FO_long_id) {
_id = reader.get_iterator().get_remaining_bytes();
return true;
}
return FltBead::extract_ancillary(reader);
}
////////////////////////////////////////////////////////////////////
// Function: FltBeadID::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltBeadID::
build_record(FltRecordWriter &writer) const {
if (!FltBead::build_record(writer)) {
return false;
}
writer.update_datagram().add_fixed_string(_id.substr(0, 7), 8);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltBeadID::write_ancillary
// Access: Protected, Virtual
// Description: Writes whatever ancillary records are required for
// this record. Returns FE_ok on success, or something
// else if there is some error.
////////////////////////////////////////////////////////////////////
FltError FltBeadID::
write_ancillary(FltRecordWriter &writer) const {
if (_id.length() > 7) {
Datagram dc(_id);
FltError result = writer.write_record(FO_long_id, dc);
if (result != FE_ok) {
return result;
}
}
return FltBead::write_ancillary(writer);
}

View File

@ -0,0 +1,57 @@
// Filename: fltBeadID.h
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTBEADID_H
#define FLTBEADID_H
#include <pandatoolbase.h>
#include "fltBead.h"
////////////////////////////////////////////////////////////////////
// Class : FltBeadID
// Description : A base class for any of a broad family of flt beads
// that include an ID.
////////////////////////////////////////////////////////////////////
class FltBeadID : public FltBead {
public:
FltBeadID(FltHeader *header);
const string &get_id() const;
void set_id(const string &id);
virtual void output(ostream &out) const;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool extract_ancillary(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
virtual FltError write_ancillary(FltRecordWriter &writer) const;
private:
string _id;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltBead::init_type();
register_type(_type_handle, "FltBeadID",
FltBead::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#endif

View File

@ -0,0 +1,47 @@
// Filename: fltError.cxx
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltError.h"
ostream &
operator << (ostream &out, FltError error) {
switch (error) {
case FE_ok:
return out << "no error";
case FE_could_not_open:
return out << "could not open file";
case FE_empty_file:
return out << "empty file";
case FE_end_of_file:
return out << "unexpected end of file";
case FE_read_error:
return out << "read error on file";
case FE_invalid_record:
return out << "invalid record";
case FE_extra_data:
return out << "extra data at end of file";
case FE_write_error:
return out << "write error on file";
case FE_bad_data:
return out << "bad data";
case FE_not_implemented:
return out << "not implemented";
case FE_internal:
return out << "internal error";
default:
return out << "unknown error " << (int)error;
}
}

View File

@ -0,0 +1,32 @@
// Filename: fltError.h
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTERROR_H
#define FLTERROR_H
#include <pandatoolbase.h>
// Return values for various functions in the flt library.
enum FltError {
FE_ok = 0,
FE_could_not_open,
FE_empty_file,
FE_end_of_file,
FE_read_error,
FE_invalid_record,
FE_extra_data,
FE_write_error,
FE_bad_data,
FE_not_implemented,
FE_undefined_instance,
FE_internal
};
ostream &operator << (ostream &out, FltError error);
#endif

View File

@ -0,0 +1,107 @@
// Filename: fltExternalReference.cxx
// Created by: drose (30Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltExternalReference.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
TypeHandle FltExternalReference::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltExternalReference::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltExternalReference::
FltExternalReference(FltHeader *header) : FltBead(header) {
_flags = 0;
}
////////////////////////////////////////////////////////////////////
// Function: FltExternalReference::output
// Access: Public
// Description: Writes a quick one-line description of the record, but
// not its children. This is a human-readable
// description, primarily for debugging; to write a flt
// file, use FltHeader::write_flt().
////////////////////////////////////////////////////////////////////
void FltExternalReference::
output(ostream &out) const {
out << "External " << _filename;
if (!_bead_id.empty()) {
out << " (" << _bead_id << ")";
}
}
////////////////////////////////////////////////////////////////////
// Function: FltExternalReference::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this bead based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltExternalReference::
extract_record(FltRecordReader &reader) {
if (!FltBead::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_external_ref, false);
DatagramIterator &iterator = reader.get_iterator();
string name = iterator.get_fixed_string(200);
iterator.skip_bytes(1 + 1);
iterator.skip_bytes(2); // Undocumented additional padding.
_flags = iterator.get_be_uint32();
iterator.skip_bytes(2);
iterator.skip_bytes(2); // Undocumented additional padding.
_filename = name;
if (!name.empty() && name[name.length() - 1] == '>') {
// Extract out the bead name.
size_t open = name.rfind('<');
if (open != string::npos) {
_filename = name.substr(0, open);
_bead_id = name.substr(open + 1, name.length() - open - 2);
}
}
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltExternalReference::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltExternalReference::
build_record(FltRecordWriter &writer) const {
if (!FltBead::build_record(writer)) {
return false;
}
writer.set_opcode(FO_external_ref);
Datagram &datagram = writer.update_datagram();
string name = _filename;
if (!_bead_id.empty()) {
name += "<" + _bead_id + ">";
}
datagram.add_fixed_string(name.substr(0, 199), 200);
datagram.pad_bytes(1 + 1);
datagram.pad_bytes(2); // Undocumented additional padding.
datagram.add_be_uint32(_flags);
datagram.pad_bytes(2);
datagram.pad_bytes(2); // Undocumented additional padding.
return true;
}

View File

@ -0,0 +1,63 @@
// Filename: fltExternalReference.h
// Created by: drose (30Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTEXTERNALREFERENCE_H
#define FLTEXTERNALREFERENCE_H
#include <pandatoolbase.h>
#include "fltBead.h"
#include <filename.h>
////////////////////////////////////////////////////////////////////
// Class : FltExternalReference
// Description : An external reference to another flt file (possibly
// to a specific bead within the flt file).
////////////////////////////////////////////////////////////////////
class FltExternalReference : public FltBead {
public:
FltExternalReference(FltHeader *header);
virtual void output(ostream &out) const;
enum Flags {
F_color_palette_override = 0x80000000,
F_material_palette_override = 0x40000000,
F_texture_palette_override = 0x20000000,
F_line_style_palette_override = 0x10000000,
F_sound_palette_override = 0x08000000,
F_light_palette_override = 0x04000000
};
Filename _filename;
string _bead_id;
int _flags;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltBead::init_type();
register_type(_type_handle, "FltExternalReference",
FltBead::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#endif

View File

@ -0,0 +1,133 @@
// Filename: fltEyepoint.cxx
// Created by: drose (26Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltEyepoint.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
////////////////////////////////////////////////////////////////////
// Function: FltEyepoint::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltEyepoint::
FltEyepoint() {
_rotation_center.set(0.0, 0.0, 0.0);
_hpr.set(0.0, 0.0, 0.0);
_rotation = LMatrix4f::ident_mat();
_fov = 60.0;
_scale = 1.0;
_near_clip = 0.1;
_far_clip = 10000.0;
_fly_through = LMatrix4f::ident_mat();
_eyepoint.set(0.0, 0.0, 0.0);
_fly_through_yaw = 0.0;
_fly_through_pitch = 0.0;
_eyepoint_direction.set(0.0, 1.0, 0.0);
_no_fly_through = true;
_ortho_mode = false;
_is_valid = true;
_image_offset_x = 0;
_image_offset_y = 0;
_image_zoom = 1;
}
////////////////////////////////////////////////////////////////////
// Function: FltEyepoint::extract_record
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool FltEyepoint::
extract_record(FltRecordReader &reader) {
DatagramIterator &iterator = reader.get_iterator();
_rotation_center[0] = iterator.get_be_float64();
_rotation_center[1] = iterator.get_be_float64();
_rotation_center[2] = iterator.get_be_float64();
_hpr[0] = iterator.get_be_float32();
_hpr[1] = iterator.get_be_float32();
_hpr[2] = iterator.get_be_float32();
int r;
for (r = 0; r < 4; r++) {
for (int c = 0; c < 4; c++) {
_rotation(r, c) = iterator.get_be_float32();
}
}
_fov = iterator.get_be_float32();
_scale = iterator.get_be_float32();
_near_clip = iterator.get_be_float32();
_far_clip = iterator.get_be_float32();
for (r = 0; r < 4; r++) {
for (int c = 0; c < 4; c++) {
_fly_through(r, c) = iterator.get_be_float32();
}
}
_eyepoint[0] = iterator.get_be_float32();
_eyepoint[1] = iterator.get_be_float32();
_eyepoint[2] = iterator.get_be_float32();
_fly_through_yaw = iterator.get_be_float32();
_fly_through_pitch = iterator.get_be_float32();
_eyepoint_direction[0] = iterator.get_be_float32();
_eyepoint_direction[1] = iterator.get_be_float32();
_eyepoint_direction[2] = iterator.get_be_float32();
_no_fly_through = (iterator.get_be_int32() != 0);
_ortho_mode = (iterator.get_be_int32() != 0);
_is_valid = (iterator.get_be_int32() != 0);
_image_offset_x = iterator.get_be_int32();
_image_offset_y = iterator.get_be_int32();
_image_zoom = iterator.get_be_int32();
iterator.skip_bytes(4*9);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltEyepoint::build_record
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool FltEyepoint::
build_record(FltRecordWriter &writer) const {
Datagram &datagram = writer.update_datagram();
datagram.add_be_float64(_rotation_center[0]);
datagram.add_be_float64(_rotation_center[1]);
datagram.add_be_float64(_rotation_center[2]);
datagram.add_be_float32(_hpr[0]);
datagram.add_be_float32(_hpr[1]);
datagram.add_be_float32(_hpr[2]);
int r;
for (r = 0; r < 4; r++) {
for (int c = 0; c < 4; c++) {
datagram.add_be_float32(_rotation(r, c));
}
}
datagram.add_be_float32(_fov);
datagram.add_be_float32(_scale);
datagram.add_be_float32(_near_clip);
datagram.add_be_float32(_far_clip);
for (r = 0; r < 4; r++) {
for (int c = 0; c < 4; c++) {
datagram.add_be_float32(_fly_through(r, c));
}
}
datagram.add_be_float32(_eyepoint[0]);
datagram.add_be_float32(_eyepoint[1]);
datagram.add_be_float32(_eyepoint[2]);
datagram.add_be_float32(_fly_through_yaw);
datagram.add_be_float32(_fly_through_pitch);
datagram.add_be_float32(_eyepoint_direction[0]);
datagram.add_be_float32(_eyepoint_direction[1]);
datagram.add_be_float32(_eyepoint_direction[2]);
datagram.add_be_int32(_no_fly_through);
datagram.add_be_int32(_ortho_mode);
datagram.add_be_int32(_is_valid);
datagram.add_be_int32(_image_offset_x);
datagram.add_be_int32(_image_offset_y);
datagram.add_be_int32(_image_zoom);
datagram.pad_bytes(4*9);
return true;
}

View File

@ -0,0 +1,52 @@
// Filename: fltEyepoint.h
// Created by: drose (26Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTEYEPOINT_H
#define FLTEYEPOINT_H
#include <pandatoolbase.h>
#include <luse.h>
class FltRecordReader;
class FltRecordWriter;
////////////////////////////////////////////////////////////////////
// Class : FltEyepoint
// Description : A single eyepoint entry in the eyepoint/trackplane
// palette.
////////////////////////////////////////////////////////////////////
class FltEyepoint {
public:
FltEyepoint();
bool extract_record(FltRecordReader &reader);
bool build_record(FltRecordWriter &writer) const;
public:
LPoint3d _rotation_center;
LVecBase3f _hpr;
LMatrix4f _rotation;
float _fov;
float _scale;
float _near_clip;
float _far_clip;
LMatrix4f _fly_through;
LPoint3f _eyepoint;
float _fly_through_yaw;
float _fly_through_pitch;
LVector3f _eyepoint_direction;
bool _no_fly_through;
bool _ortho_mode;
bool _is_valid;
int _image_offset_x;
int _image_offset_y;
int _image_zoom;
};
#endif

View File

@ -0,0 +1,60 @@
// Filename: fltFace.I
// Created by: drose (30Aug00)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: FltFace::has_texture
// Access: Public
// Description: Returns true if the face has a texture applied, false
// otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool FltFace::
has_texture() const {
return (_texture_index >= 0 && _header->has_texture(_texture_index));
}
////////////////////////////////////////////////////////////////////
// Function: FltFace::get_texture
// Access: Public
// Description: Returns the texture applied to this face, or NULL if
// no texture was applied.
////////////////////////////////////////////////////////////////////
INLINE FltTexture *FltFace::
get_texture() const {
return _header->get_texture(_texture_index);
}
////////////////////////////////////////////////////////////////////
// Function: FltFace::has_material
// Access: Public
// Description: Returns true if the face has a material applied, false
// otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool FltFace::
has_material() const {
return (_material_index >= 0 && _header->has_material(_material_index));
}
////////////////////////////////////////////////////////////////////
// Function: FltFace::get_material
// Access: Public
// Description: Returns the material applied to this face, or NULL if
// no material was applied.
////////////////////////////////////////////////////////////////////
INLINE FltMaterial *FltFace::
get_material() const {
return _header->get_material(_material_index);
}
////////////////////////////////////////////////////////////////////
// Function: FltFace::has_color
// Access: Public
// Description: Returns true if the face has a primary color
// indicated, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool FltFace::
has_color() const {
return ((_flags & F_no_color) == 0) || has_material();
}

View File

@ -0,0 +1,250 @@
// Filename: fltFace.cxx
// Created by: drose (25Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltFace.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
#include "fltHeader.h"
#include "fltMaterial.h"
TypeHandle FltFace::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltFace::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltFace::
FltFace(FltHeader *header) : FltBeadID(header) {
_ir_color = 0;
_relative_priority = 0;
_draw_type = DT_solid_backface;
_texwhite = false;
_color_name_index = 0;
_alt_color_name_index = 0;
_billboard_type = BT_none;
_detail_texture_index = -1;
_texture_index = -1;
_material_index = -1;
_dfad_material_code = 0;
_dfad_feature_id = 0;
_ir_material_code = 0;
_transparency = 0;
_lod_generation_control = 0;
_line_style_index = 0;
_flags = 0;
_light_mode = LM_face_no_normal;
_texture_mapping_index = 0;
_color_index = 0;
_alt_color_index = 0;
}
////////////////////////////////////////////////////////////////////
// Function: FltFace::get_color
// Access: Public
// Description: If has_color() indicates true, returns the primary
// color of the face, as a four-component value
// (including alpha as the transparency channel).
////////////////////////////////////////////////////////////////////
Colorf FltFace::
get_color() const {
nassertr(has_color(), Colorf(0.0, 0.0, 0.0, 0.0));
if (_texwhite && has_texture()) {
// Force this one white.
return Colorf(1.0, 1.0, 1.0, 1.0 - (_transparency / 65535.0));
}
if (has_material()) {
// If we have a material, that replaces the color.
FltMaterial *material = get_material();
return Colorf(material->_diffuse[0],
material->_diffuse[1],
material->_diffuse[2],
1.0 - (_transparency / 65535.0));
}
return _header->get_color(_color_index, (_flags & F_packed_color) != 0,
_packed_color, _transparency);
}
////////////////////////////////////////////////////////////////////
// Function: FltFace::get_rgb
// Access: Public
// Description: If has_color() indicates true, returns the primary
// color of the face, as a three-component value
// ignoring transparency.
////////////////////////////////////////////////////////////////////
RGBColorf FltFace::
get_rgb() const {
nassertr(has_color(), RGBColorf(0.0, 0.0, 0.0));
if (_texwhite && has_texture()) {
// Force this one white.
return RGBColorf(1.0, 1.0, 1.0);
}
if (has_material()) {
// If we have a material, that replaces the color.
FltMaterial *material = get_material();
return material->_diffuse;
}
return _header->get_rgb(_color_index, (_flags & F_packed_color) != 0,
_packed_color);
}
////////////////////////////////////////////////////////////////////
// Function: FltFace::has_alt_color
// Access: Public
// Description: Returns true if the face has an alternate color
// indicated, false otherwise.
////////////////////////////////////////////////////////////////////
bool FltFace::
has_alt_color() const {
return (_flags & F_no_alt_color) == 0;
}
////////////////////////////////////////////////////////////////////
// Function: FltFace::get_alt_color
// Access: Public
// Description: If has_alt_color() indicates true, returns the alternate
// color of the face, as a four-component value
// (including alpha as the transparency channel).
////////////////////////////////////////////////////////////////////
Colorf FltFace::
get_alt_color() const {
nassertr(has_alt_color(), Colorf(0.0, 0.0, 0.0, 0.0));
return _header->get_color(_alt_color_index, (_flags & F_packed_color) != 0,
_alt_packed_color, _transparency);
}
////////////////////////////////////////////////////////////////////
// Function: FltFace::get_alt_rgb
// Access: Public
// Description: If has_alt_color() indicates true, returns the alternate
// color of the face, as a three-component value
// ignoring transparency.
////////////////////////////////////////////////////////////////////
RGBColorf FltFace::
get_alt_rgb() const {
nassertr(has_alt_color(), RGBColorf(0.0, 0.0, 0.0));
return _header->get_rgb(_alt_color_index, (_flags & F_packed_color) != 0,
_alt_packed_color);
}
////////////////////////////////////////////////////////////////////
// Function: FltFace::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this bead based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltFace::
extract_record(FltRecordReader &reader) {
if (!FltBeadID::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_face, false);
DatagramIterator &iterator = reader.get_iterator();
_ir_color = iterator.get_be_int32();
_relative_priority = iterator.get_be_int16();
_draw_type = (DrawType)iterator.get_int8();
_texwhite = (iterator.get_int8() != 0);
_color_name_index = iterator.get_be_int16();
_alt_color_name_index = iterator.get_be_int16();
iterator.skip_bytes(1);
_billboard_type = (BillboardType)iterator.get_int8();
_detail_texture_index = iterator.get_be_int16();
_texture_index = iterator.get_be_int16();
_material_index = iterator.get_be_int16();
_dfad_material_code = iterator.get_be_int16();
_dfad_feature_id = iterator.get_be_int16();
_ir_material_code = iterator.get_be_int32();
_transparency = iterator.get_be_uint16();
_lod_generation_control = iterator.get_uint8();
_line_style_index = iterator.get_uint8();
_flags = iterator.get_be_uint32();
_light_mode = (LightMode)iterator.get_uint8();
iterator.skip_bytes(1 + 4);
iterator.skip_bytes(2); // Undocumented padding.
if (!_packed_color.extract_record(reader)) {
return false;
}
if (!_alt_packed_color.extract_record(reader)) {
return false;
}
_texture_mapping_index = iterator.get_be_int16();
iterator.skip_bytes(2);
_color_index = iterator.get_be_uint32();
_alt_color_index = iterator.get_be_uint32();
iterator.skip_bytes(2 + 2);
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltFace::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltFace::
build_record(FltRecordWriter &writer) const {
if (!FltBeadID::build_record(writer)) {
return false;
}
writer.set_opcode(FO_face);
Datagram &datagram = writer.update_datagram();
datagram.add_be_int32(_ir_color);
datagram.add_be_int16(_relative_priority);
datagram.add_int8(_draw_type);
datagram.add_int8(_texwhite);
datagram.add_be_uint16(_color_name_index);
datagram.add_be_uint16(_alt_color_name_index);
datagram.pad_bytes(1);
datagram.add_int8(_billboard_type);
datagram.add_be_int16(_detail_texture_index);
datagram.add_be_int16(_texture_index);
datagram.add_be_int16(_material_index);
datagram.add_be_int16(_dfad_material_code);
datagram.add_be_int16(_dfad_feature_id);
datagram.add_be_int32(_ir_material_code);
datagram.add_be_uint16(_transparency);
datagram.add_uint8(_lod_generation_control);
datagram.add_uint8(_line_style_index);
datagram.add_be_uint32(_flags);
datagram.add_uint8(_light_mode);
datagram.pad_bytes(1 + 4);
datagram.pad_bytes(2); // Undocumented padding.
if (!_packed_color.build_record(writer)) {
return false;
}
if (!_alt_packed_color.build_record(writer)) {
return false;
}
datagram.add_be_int16(_texture_mapping_index);
datagram.pad_bytes(2);
datagram.add_be_uint32(_color_index);
datagram.add_be_uint32(_alt_color_index);
datagram.pad_bytes(2 + 2);
return true;
}

128
pandatool/src/flt/fltFace.h Normal file
View File

@ -0,0 +1,128 @@
// Filename: fltFace.h
// Created by: drose (25Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTFACE_H
#define FLTFACE_H
#include <pandatoolbase.h>
#include "fltBeadID.h"
#include "fltPackedColor.h"
#include "fltHeader.h"
#include <luse.h>
class FltTexture;
class FltMaterial;
////////////////////////////////////////////////////////////////////
// Class : FltFace
// Description : A single face bead, e.g. a polygon.
////////////////////////////////////////////////////////////////////
class FltFace : public FltBeadID {
public:
FltFace(FltHeader *header);
enum DrawType {
DT_solid_backface = 0,
DT_solid_no_backface = 1,
DT_wireframe = 2,
DT_wireframe_close = 3,
DT_wireframe_highlight = 4,
DT_omni_light = 5,
DT_uni_light = 6,
DT_bi_light = 7
};
enum BillboardType {
BT_none = 0,
BT_fixed = 1,
BT_axial = 2,
BT_point = 4
};
enum Flags {
F_terrain = 0x80000000,
F_no_color = 0x40000000,
F_no_alt_color = 0x20000000,
F_packed_color = 0x10000000,
F_terrain_footprint = 0x08000000,
F_hidden = 0x04000000
};
enum LightMode {
LM_face_no_normal = 0,
LM_vertex_no_normal = 1,
LM_face_with_normal = 2,
LM_vertex_with_normal = 3
};
int _ir_color;
int _relative_priority;
DrawType _draw_type;
bool _texwhite;
int _color_name_index;
int _alt_color_name_index;
BillboardType _billboard_type;
int _detail_texture_index;
int _texture_index;
int _material_index;
int _dfad_material_code;
int _dfad_feature_id;
int _ir_material_code;
int _transparency;
int _lod_generation_control;
int _line_style_index;
unsigned int _flags;
LightMode _light_mode;
FltPackedColor _packed_color;
FltPackedColor _alt_packed_color;
int _texture_mapping_index;
unsigned int _color_index;
unsigned int _alt_color_index;
public:
INLINE bool has_texture() const;
INLINE FltTexture *get_texture() const;
INLINE bool has_material() const;
INLINE FltMaterial *get_material() const;
INLINE bool has_color() const;
Colorf get_color() const;
RGBColorf get_rgb() const;
bool has_alt_color() const;
Colorf get_alt_color() const;
RGBColorf get_alt_rgb() const;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltBeadID::init_type();
register_type(_type_handle, "FltFace",
FltBeadID::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "fltFace.I"
#endif

View File

@ -0,0 +1,84 @@
// Filename: fltGroup.cxx
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltGroup.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
TypeHandle FltGroup::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltGroup::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltGroup::
FltGroup(FltHeader *header) : FltBeadID(header) {
_relative_priority = 0;
_flags = 0;
_special_id1 = 0;
_special_id2 = 0;
_significance = 0;
_layer_id = 0;
}
////////////////////////////////////////////////////////////////////
// Function: FltGroup::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this bead based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltGroup::
extract_record(FltRecordReader &reader) {
if (!FltBeadID::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_group, false);
DatagramIterator &iterator = reader.get_iterator();
_relative_priority = iterator.get_be_int16();
iterator.skip_bytes(2);
_flags = iterator.get_be_uint32();
_special_id1 = iterator.get_be_int16();
_special_id2 = iterator.get_be_int16();
_significance = iterator.get_be_int16();
_layer_id = iterator.get_int8();
iterator.skip_bytes(5);
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltGroup::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltGroup::
build_record(FltRecordWriter &writer) const {
if (!FltBeadID::build_record(writer)) {
return false;
}
writer.set_opcode(FO_group);
Datagram &datagram = writer.update_datagram();
datagram.add_be_int16(_relative_priority);
datagram.pad_bytes(2);
datagram.add_be_uint32(_flags);
datagram.add_be_int16(_special_id1);
datagram.add_be_int16(_special_id2);
datagram.add_be_int16(_significance);
datagram.add_int8(_layer_id);
datagram.pad_bytes(5);
return true;
}

View File

@ -0,0 +1,59 @@
// Filename: fltGroup.h
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTGROUP_H
#define FLTGROUP_H
#include <pandatoolbase.h>
#include "fltBeadID.h"
////////////////////////////////////////////////////////////////////
// Class : FltGroup
// Description : The main grouping bead of the flt file.
////////////////////////////////////////////////////////////////////
class FltGroup : public FltBeadID {
public:
FltGroup(FltHeader *header);
enum Flags {
F_forward_animation = 0x40000000,
F_swing_animation = 0x20000000,
F_bounding_box = 0x10000000,
F_freeze_bounding_box = 0x08000000,
F_default_parent = 0x04000000,
};
int _relative_priority;
unsigned int _flags;
int _special_id1, _special_id2;
int _significance;
int _layer_id;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltBeadID::init_type();
register_type(_type_handle, "FltGroup",
FltBeadID::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,310 @@
// Filename: fltHeader.h
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTHEADER_H
#define FLTHEADER_H
#include <pandatoolbase.h>
#include "fltBeadID.h"
#include "fltVertex.h"
#include "fltMaterial.h"
#include "fltTexture.h"
#include "fltLightSourceDefinition.h"
#include "fltEyepoint.h"
#include "fltTrackplane.h"
#include "fltInstanceDefinition.h"
#include <filename.h>
#include <dSearchPath.h>
////////////////////////////////////////////////////////////////////
// Class : FltHeader
// Description : This is the first bead in the file, the top of the
// bead hierarchy, and the primary interface to reading
// and writing a Flt file. You always read a Flt file
// by creating a header and calling read_flt(), which
// fills in its children beads automatically; you write
// a Flt file by creating a header, adding its children,
// and calling write_flt().
////////////////////////////////////////////////////////////////////
class FltHeader : public FltBeadID {
public:
FltHeader();
FltError read_flt(Filename filename);
FltError read_flt(istream &in);
FltError write_flt(Filename filename);
FltError write_flt(ostream &out);
enum AttrUpdate {
AU_none,
AU_if_missing,
AU_always
};
void set_auto_attr_update(AttrUpdate attr);
AttrUpdate get_auto_attr_update() const;
enum Units {
U_meters = 0,
U_kilometers = 1,
U_feet = 4,
U_inches = 5,
U_nautical_miles = 8
};
enum Flags {
F_save_vertex_normals = 0x80000000
};
enum ProjectionType {
PT_flat_earth = 0,
PT_trapezoidal = 1,
PT_round_earth = 2,
PT_lambert = 3,
PT_utm = 4
};
enum VertexStorageType {
VTS_double = 1
};
enum DatabaseOrigin {
DO_open_flight = 100,
DO_dig = 200,
DO_es_ct6 = 300,
DO_psp = 400,
DO_ge_civ = 600,
DO_es_gdf = 700,
};
enum EarthModel {
EM_wgs84 = 0,
EM_wgs72 = 1,
EM_bessel = 2,
EM_clarke_1866 = 3,
EM_nad27 = 4
};
int _format_revision_level;
int _edit_revision_level;
string _last_revision;
int _next_group_id;
int _next_lod_id;
int _next_object_id;
int _next_face_id;
int _unit_multiplier;
Units _vertex_units;
bool _texwhite_new;
unsigned int _flags;
ProjectionType _projection_type;
int _next_dof_id;
VertexStorageType _vertex_storage_type;
DatabaseOrigin _database_origin;
double _sw_x, _sw_y;
double _delta_x, _delta_y;
int _next_sound_id;
int _next_path_id;
int _next_clip_id;
int _next_text_id;
int _next_bsp_id;
int _next_switch_id;
double _sw_lat, _sw_long;
double _ne_lat, _ne_long;
double _origin_lat, _origin_long;
double _lambert_upper_lat, _lambert_lower_lat;
int _next_light_id;
int _next_road_id;
int _next_cat_id;
EarthModel _earth_model;
public:
double get_flt_version() const;
static double min_flt_version();
static double max_flt_version();
// Accessors into the instance pool.
bool has_instance(int instance_index) const;
FltInstanceDefinition *get_instance(int instance_index) const;
void clear_instances();
void add_instance(FltInstanceDefinition *instance);
void remove_instance(int instance_index);
// Accessors into the vertex palette.
int get_num_vertices() const;
FltVertex *get_vertex(int n) const;
void clear_vertices();
void add_vertex(FltVertex *vertex);
FltVertex *get_vertex_by_offset(int offset);
int get_offset_by_vertex(FltVertex *vertex);
// Accessors into the color palette. This is read-only; why would
// you want to mess with building a new color palette?
int get_num_colors() const;
Colorf get_color(int color_index) const;
RGBColorf get_rgb(int color_index) const;
bool has_color_name(int color_index) const;
string get_color_name(int color_index) const;
int get_closest_color(Colorf color) const;
int get_closest_rgb(RGBColorf color) const;
int get_num_color_entries() const;
int get_num_color_shades() const;
// These functions are mainly used behind-the-scenes to decode the
// strange forest of color options defined for faces and vertices.
Colorf get_color(int color_index, bool use_packed_color,
const FltPackedColor &packed_color,
int transparency);
RGBColorf get_rgb(int color_index, bool use_packed_color,
const FltPackedColor &packed_color);
// Accessors into the material palette.
bool has_material(int material_index) const;
FltMaterial *get_material(int material_index) const;
void clear_materials();
void add_material(FltMaterial *material);
void remove_material(int material_index);
// Accessors into the texture palette.
bool has_texture(int texture_index) const;
FltTexture *get_texture(int texture_index) const;
void clear_textures();
void add_texture(FltTexture *texture);
void remove_texture(int texture_index);
// Sometimes Flt files store textures as relative pathnames.
// Setting this search path helps resolve that tendency.
void set_texture_path(const DSearchPath &path);
DSearchPath &update_texture_path();
const DSearchPath &get_texture_path() const;
// Accessors into the light source palette.
bool has_light_source(int light_index) const;
FltLightSourceDefinition *get_light_source(int light_index) const;
void clear_light_sources();
void add_light_source(FltLightSourceDefinition *light_source);
void remove_light_source(int light_index);
// Accessors into the eyepoint/trackplane palette.
bool got_eyepoint_trackplane_palette() const;
void set_eyepoint_trackplane_palette(bool flag);
int get_num_eyepoints() const;
FltEyepoint *get_eyepoint(int n);
int get_num_trackplanes() const;
FltTrackplane *get_trackplane(int n);
private:
// Instance subtrees. These are standalone subtrees, which may be
// referenced by various points in the hierarchy, stored by instance
// ID number.
typedef map<int, PT(FltInstanceDefinition)> Instances;
Instances _instances;
// Support for the vertex palette.
int update_vertex_lookups();
typedef vector<PT(FltVertex)> Vertices;
typedef set<FltVertex *> UniqueVertices;
typedef map<int, FltVertex *> VerticesByOffset;
typedef map<FltVertex *, int> OffsetsByVertex;
Vertices _vertices;
UniqueVertices _unique_vertices;
VerticesByOffset _vertices_by_offset;
OffsetsByVertex _offsets_by_vertex;
bool _vertex_lookups_stale;
// This is maintained while the header is being read, to map the
// vertices to their corresponding offsets in the vertex palette.
int _current_vertex_offset;
// Support for the color palette.
typedef vector<FltPackedColor> Colors;
typedef map<int, string> ColorNames;
Colors _colors;
ColorNames _color_names;
// Support for the material palette.
typedef map<int, PT(FltMaterial)> Materials;
Materials _materials;
// Support for the texture palette.
AttrUpdate _auto_attr_update;
typedef map<int, PT(FltTexture)> Textures;
Textures _textures;
DSearchPath _texture_path;
// Support for the light source palette.
typedef map<int, PT(FltLightSourceDefinition)> LightSources;
LightSources _light_sources;
// Support for the eyepoint/trackplane palette.
bool _got_eyepoint_trackplane_palette;
FltEyepoint _eyepoints[10];
FltTrackplane _trackplanes[10];
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool extract_ancillary(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
virtual FltError write_ancillary(FltRecordWriter &writer) const;
private:
bool extract_vertex(FltRecordReader &reader);
bool extract_color_palette(FltRecordReader &reader);
bool extract_material(FltRecordReader &reader);
bool extract_texture(FltRecordReader &reader);
bool extract_light_source(FltRecordReader &reader);
bool extract_eyepoint_palette(FltRecordReader &reader);
FltError write_vertex_palette(FltRecordWriter &writer) const;
FltError write_color_palette(FltRecordWriter &writer) const;
FltError write_material_palette(FltRecordWriter &writer) const;
FltError write_texture_palette(FltRecordWriter &writer) const;
FltError write_light_source_palette(FltRecordWriter &writer) const;
FltError write_eyepoint_palette(FltRecordWriter &writer) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltBeadID::init_type();
register_type(_type_handle, "FltHeader",
FltBeadID::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#endif

View File

@ -0,0 +1,67 @@
// Filename: fltInstanceDefinition.cxx
// Created by: drose (30Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltInstanceDefinition.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
TypeHandle FltInstanceDefinition::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltInstanceDefinition::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltInstanceDefinition::
FltInstanceDefinition(FltHeader *header) : FltBead(header) {
_instance_index = 0;
}
////////////////////////////////////////////////////////////////////
// Function: FltInstanceDefinition::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this bead based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltInstanceDefinition::
extract_record(FltRecordReader &reader) {
if (!FltBead::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_instance, false);
DatagramIterator &iterator = reader.get_iterator();
iterator.skip_bytes(2);
_instance_index = iterator.get_be_int16();
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltInstanceDefinition::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltInstanceDefinition::
build_record(FltRecordWriter &writer) const {
if (!FltBead::build_record(writer)) {
return false;
}
writer.set_opcode(FO_instance);
Datagram &datagram = writer.update_datagram();
datagram.pad_bytes(2);
datagram.add_be_int16(_instance_index);
return true;
}

View File

@ -0,0 +1,56 @@
// Filename: fltInstanceDefinition.h
// Created by: drose (30Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTINSTANCEDEFINITION_H
#define FLTINSTANCEDEFINITION_H
#include <pandatoolbase.h>
#include "fltBead.h"
////////////////////////////////////////////////////////////////////
// Class : FltInstanceDefinition
// Description : This special kind of record marks the top node of an
// instance subtree. This subtree lives outside of the
// normal hierarchy, and is MultiGen's way of support
// instancing--each instance subtree has a unique index,
// which may be referenced in a FltInstanceRef object to
// make the instance appear in various places in the
// hierarchy.
////////////////////////////////////////////////////////////////////
class FltInstanceDefinition : public FltBead {
public:
FltInstanceDefinition(FltHeader *header);
int _instance_index;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltBead::init_type();
register_type(_type_handle, "FltInstanceDefinition",
FltBead::get_class_type());
}
private:
static TypeHandle _type_handle;
friend class FltInstanceRef;
friend class FltRecordWriter;
};
#endif

View File

@ -0,0 +1,108 @@
// Filename: fltInstanceRef.cxx
// Created by: drose (30Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltInstanceRef.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
#include "fltInstanceDefinition.h"
#include "fltHeader.h"
TypeHandle FltInstanceRef::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltInstanceRef::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltInstanceRef::
FltInstanceRef(FltHeader *header) : FltBead(header) {
_instance_index = 0;
}
////////////////////////////////////////////////////////////////////
// Function: FltInstanceRef::write
// Access: Public
// Description: Writes a multiple-line description of the record and
// all of its children. This is a human-readable
// description, primarily for debugging; to write a flt
// file, use FltHeader::write_flt().
////////////////////////////////////////////////////////////////////
void FltInstanceRef::
write(ostream &out, int indent_level) const {
indent(out, indent_level) << "instance";
FltInstanceDefinition *def = _header->get_instance(_instance_index);
if (def != (FltInstanceDefinition *)NULL) {
def->write_children(out, indent_level + 2);
indent(out, indent_level) << "}\n";
} else {
out << "\n";
}
}
////////////////////////////////////////////////////////////////////
// Function: FltInstanceRef::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this bead based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltInstanceRef::
extract_record(FltRecordReader &reader) {
if (!FltBead::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_instance_ref, false);
DatagramIterator &iterator = reader.get_iterator();
iterator.skip_bytes(2);
_instance_index = iterator.get_be_int16();
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltInstanceRef::write_record_and_children
// Access: Protected, Virtual
// Description: Writes this record out to the flt file, along with all
// of its ancillary records and children records. Returns
// FE_ok on success, or something else on error.
////////////////////////////////////////////////////////////////////
FltError FltInstanceRef::
write_record_and_children(FltRecordWriter &writer) const {
// First, make sure our instance definition has already been written.
FltError result = writer.write_instance_def(_header, _instance_index);
if (result != FE_ok) {
return result;
}
// Then write out our own record.
return FltBead::write_record_and_children(writer);
}
////////////////////////////////////////////////////////////////////
// Function: FltInstanceRef::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltInstanceRef::
build_record(FltRecordWriter &writer) const {
if (!FltBead::build_record(writer)) {
return false;
}
writer.set_opcode(FO_instance_ref);
Datagram &datagram = writer.update_datagram();
datagram.pad_bytes(2);
datagram.add_be_int16(_instance_index);
return true;
}

View File

@ -0,0 +1,54 @@
// Filename: fltInstanceRef.h
// Created by: drose (30Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTINSTANCEREF_H
#define FLTINSTANCEREF_H
#include <pandatoolbase.h>
#include "fltBead.h"
////////////////////////////////////////////////////////////////////
// Class : FltInstanceRef
// Description : This bead appears in the hierarchy to refer to a
// FltInstanceDefinition node defined elsewhere. It
// indicates that the subtree beginning at the
// FltInstanceDefinition should be considered to be
// instanced here.
////////////////////////////////////////////////////////////////////
class FltInstanceRef : public FltBead {
public:
FltInstanceRef(FltHeader *header);
int _instance_index;
virtual void write(ostream &out, int indent_level = 0) const;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual FltError write_record_and_children(FltRecordWriter &writer) const;
virtual bool build_record(FltRecordWriter &writer) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltBead::init_type();
register_type(_type_handle, "FltInstanceRef",
FltBead::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#endif

View File

@ -0,0 +1,91 @@
// Filename: fltLOD.cxx
// Created by: drose (25Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltLOD.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
TypeHandle FltLOD::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltLOD::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltLOD::
FltLOD(FltHeader *header) : FltBeadID(header) {
_switch_in = 0.0;
_switch_out = 0.0;
_special_id1 = 0;
_special_id2 = 0;
_flags = 0;
_center_x = 0.0;
_center_y = 0.0;
_center_z = 0.0;
_transition_range = 0.0;
}
////////////////////////////////////////////////////////////////////
// Function: FltLOD::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this bead based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltLOD::
extract_record(FltRecordReader &reader) {
if (!FltBeadID::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_lod, false);
DatagramIterator &iterator = reader.get_iterator();
iterator.skip_bytes(4);
_switch_in = iterator.get_be_float64();
_switch_out = iterator.get_be_float64();
_special_id1 = iterator.get_be_int16();
_special_id2 = iterator.get_be_int16();
_flags = iterator.get_be_uint32();
_center_x = iterator.get_be_float64();
_center_y = iterator.get_be_float64();
_center_z = iterator.get_be_float64();
_transition_range = iterator.get_be_float64();
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltLOD::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltLOD::
build_record(FltRecordWriter &writer) const {
if (!FltBeadID::build_record(writer)) {
return false;
}
writer.set_opcode(FO_lod);
Datagram &datagram = writer.update_datagram();
datagram.pad_bytes(4);
datagram.add_be_float64(_switch_in);
datagram.add_be_float64(_switch_out);
datagram.add_be_int16(_special_id1);
datagram.add_be_int16(_special_id2);
datagram.add_be_uint32(_flags);
datagram.add_be_float64(_center_x);
datagram.add_be_float64(_center_y);
datagram.add_be_float64(_center_z);
datagram.add_be_float64(_transition_range);
return true;
}

View File

@ -0,0 +1,59 @@
// Filename: fltLOD.h
// Created by: drose (25Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTLOD_H
#define FLTLOD_H
#include <pandatoolbase.h>
#include "fltBeadID.h"
////////////////////////////////////////////////////////////////////
// Class : FltLOD
// Description : A Level-of-Detail record.
////////////////////////////////////////////////////////////////////
class FltLOD : public FltBeadID {
public:
FltLOD(FltHeader *header);
enum Flags {
F_use_previous_slant = 0x80000000,
F_freeze_center = 0x20000000
};
double _switch_in;
double _switch_out;
int _special_id1, _special_id2;
unsigned int _flags;
double _center_x;
double _center_y;
double _center_z;
double _transition_range;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltBeadID::init_type();
register_type(_type_handle, "FltLOD",
FltBeadID::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#endif

View File

@ -0,0 +1,129 @@
// Filename: fltLightSourceDefinition.cxx
// Created by: drose (26Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltLightSourceDefinition.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
TypeHandle FltLightSourceDefinition::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltLightSourceDefinition::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltLightSourceDefinition::
FltLightSourceDefinition(FltHeader *header) : FltRecord(header) {
_light_index = 0;
_ambient.set(0.0, 0.0, 0.0, 1.0);
_diffuse.set(1.0, 1.0, 1.0, 1.0);
_specular.set(0.0, 0.0, 0.0, 1.0);
_light_type = LT_infinite;
_exponential_dropoff = 1.0;
_cutoff_angle = 180.0;
_yaw = 0.0;
_pitch = 0.0;
_constant_coefficient = 0.0;
_linear_coefficient = 0.0;
_quadratic_coefficient = 1.0;
_modeling_light = false;
}
////////////////////////////////////////////////////////////////////
// Function: FltLightSourceDefinition::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this record based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltLightSourceDefinition::
extract_record(FltRecordReader &reader) {
if (!FltRecord::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_light_definition, false);
DatagramIterator &iterator = reader.get_iterator();
_light_index = iterator.get_be_int32();
iterator.skip_bytes(2*4);
_light_name = iterator.get_fixed_string(20);
iterator.skip_bytes(4);
_ambient[0] = iterator.get_be_float32();
_ambient[1] = iterator.get_be_float32();
_ambient[2] = iterator.get_be_float32();
_ambient[3] = iterator.get_be_float32();
_diffuse[0] = iterator.get_be_float32();
_diffuse[1] = iterator.get_be_float32();
_diffuse[2] = iterator.get_be_float32();
_diffuse[3] = iterator.get_be_float32();
_specular[0] = iterator.get_be_float32();
_specular[1] = iterator.get_be_float32();
_specular[2] = iterator.get_be_float32();
_specular[3] = iterator.get_be_float32();
_light_type = (LightType)iterator.get_be_int32();
iterator.skip_bytes(4*10);
_exponential_dropoff = iterator.get_be_float32();
_cutoff_angle = iterator.get_be_float32();
_yaw = iterator.get_be_float32();
_pitch = iterator.get_be_float32();
_constant_coefficient = iterator.get_be_float32();
_linear_coefficient = iterator.get_be_float32();
_quadratic_coefficient = iterator.get_be_float32();
_modeling_light = (iterator.get_be_int32() != 0);
iterator.skip_bytes(4*19);
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltLightSourceDefinition::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltLightSourceDefinition::
build_record(FltRecordWriter &writer) const {
if (!FltRecord::build_record(writer)) {
return false;
}
writer.set_opcode(FO_light_definition);
Datagram &datagram = writer.update_datagram();
datagram.add_be_int32(_light_index);
datagram.pad_bytes(2*4);
datagram.add_fixed_string(_light_name, 20);
datagram.pad_bytes(4);
datagram.add_be_float32(_ambient[0]);
datagram.add_be_float32(_ambient[1]);
datagram.add_be_float32(_ambient[2]);
datagram.add_be_float32(_ambient[3]);
datagram.add_be_float32(_diffuse[0]);
datagram.add_be_float32(_diffuse[1]);
datagram.add_be_float32(_diffuse[2]);
datagram.add_be_float32(_diffuse[3]);
datagram.add_be_float32(_specular[0]);
datagram.add_be_float32(_specular[1]);
datagram.add_be_float32(_specular[2]);
datagram.add_be_float32(_specular[3]);
datagram.add_be_int32(_light_type);
datagram.pad_bytes(4*10);
datagram.add_be_float32(_exponential_dropoff);
datagram.add_be_float32(_cutoff_angle);
datagram.add_be_float32(_yaw);
datagram.add_be_float32(_pitch);
datagram.add_be_float32(_constant_coefficient);
datagram.add_be_float32(_linear_coefficient);
datagram.add_be_float32(_quadratic_coefficient);
datagram.add_be_int32(_modeling_light);
datagram.pad_bytes(4*19);
return true;
}

View File

@ -0,0 +1,77 @@
// Filename: fltLightSourceDefinition.h
// Created by: drose (26Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTLIGHTSOURCEDEFINITION_H
#define FLTLIGHTSOURCEDEFINITION_H
#include <pandatoolbase.h>
#include "fltRecord.h"
#include <luse.h>
////////////////////////////////////////////////////////////////////
// Class : FltLightSourceDefinition
// Description : Represents a single entry in the light source
// palette. This completely defines the color, etc. of
// a single light source, which may be referenced later
// by a FltLightSource bead in the hierarchy.
////////////////////////////////////////////////////////////////////
class FltLightSourceDefinition : public FltRecord {
public:
FltLightSourceDefinition(FltHeader *header);
enum LightType {
LT_infinite = 0,
LT_local = 1,
LT_spot = 2
};
int _light_index;
string _light_name;
Colorf _ambient;
Colorf _diffuse;
Colorf _specular;
LightType _light_type;
float _exponential_dropoff;
float _cutoff_angle; // in degrees
// yaw and pitch only for modeling lights, which are positioned at
// the eyepoint.
float _yaw;
float _pitch;
float _constant_coefficient;
float _linear_coefficient;
float _quadratic_coefficient;
bool _modeling_light;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltRecord::init_type();
register_type(_type_handle, "FltLightSourceDefinition",
FltRecord::get_class_type());
}
private:
static TypeHandle _type_handle;
friend class FltHeader;
};
#endif

View File

@ -0,0 +1,106 @@
// Filename: fltMaterial.cxx
// Created by: drose (25Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltMaterial.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
TypeHandle FltMaterial::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltMaterial::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltMaterial::
FltMaterial(FltHeader *header) : FltRecord(header) {
_material_index = 0;
_flags = 0;
_ambient.set(0.0, 0.0, 0.0);
_diffuse.set(0.0, 0.0, 0.0);
_specular.set(0.0, 0.0, 0.0);
_emissive.set(0.0, 0.0, 0.0);
_shininess = 0.0;
_alpha = 1.0;
}
////////////////////////////////////////////////////////////////////
// Function: FltMaterial::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this record based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltMaterial::
extract_record(FltRecordReader &reader) {
if (!FltRecord::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_15_material, false);
DatagramIterator &iterator = reader.get_iterator();
_material_index = iterator.get_be_int32();
_material_name = iterator.get_fixed_string(12);
_flags = iterator.get_be_uint32();
_ambient[0] = iterator.get_be_float32();
_ambient[1] = iterator.get_be_float32();
_ambient[2] = iterator.get_be_float32();
_diffuse[0] = iterator.get_be_float32();
_diffuse[1] = iterator.get_be_float32();
_diffuse[2] = iterator.get_be_float32();
_specular[0] = iterator.get_be_float32();
_specular[1] = iterator.get_be_float32();
_specular[2] = iterator.get_be_float32();
_emissive[0] = iterator.get_be_float32();
_emissive[1] = iterator.get_be_float32();
_emissive[2] = iterator.get_be_float32();
_shininess = iterator.get_be_float32();
_alpha = iterator.get_be_float32();
iterator.skip_bytes(4);
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltMaterial::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltMaterial::
build_record(FltRecordWriter &writer) const {
if (!FltRecord::build_record(writer)) {
return false;
}
writer.set_opcode(FO_15_material);
Datagram &datagram = writer.update_datagram();
datagram.add_be_int32(_material_index);
datagram.add_fixed_string(_material_name, 12);
datagram.add_be_uint32(_flags);
datagram.add_be_float32(_ambient[0]);
datagram.add_be_float32(_ambient[1]);
datagram.add_be_float32(_ambient[2]);
datagram.add_be_float32(_diffuse[0]);
datagram.add_be_float32(_diffuse[1]);
datagram.add_be_float32(_diffuse[2]);
datagram.add_be_float32(_specular[0]);
datagram.add_be_float32(_specular[1]);
datagram.add_be_float32(_specular[2]);
datagram.add_be_float32(_emissive[0]);
datagram.add_be_float32(_emissive[1]);
datagram.add_be_float32(_emissive[2]);
datagram.add_be_float32(_shininess);
datagram.add_be_float32(_alpha);
datagram.pad_bytes(4);
return true;
}

View File

@ -0,0 +1,63 @@
// Filename: fltMaterial.h
// Created by: drose (25Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTMATERIAL_H
#define FLTMATERIAL_H
#include <pandatoolbase.h>
#include "fltRecord.h"
#include <luse.h>
////////////////////////////////////////////////////////////////////
// Class : FltMaterial
// Description : Represents a single material in the material palette.
////////////////////////////////////////////////////////////////////
class FltMaterial : public FltRecord {
public:
FltMaterial(FltHeader *header);
enum Flags {
F_materials_used = 0x80000000,
};
int _material_index;
string _material_name;
unsigned int _flags;
RGBColorf _ambient;
RGBColorf _diffuse;
RGBColorf _specular;
RGBColorf _emissive;
float _shininess;
float _alpha;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltRecord::init_type();
register_type(_type_handle, "FltMaterial",
FltRecord::get_class_type());
}
private:
static TypeHandle _type_handle;
friend class FltHeader;
};
#endif

View File

@ -0,0 +1,76 @@
// Filename: fltObject.cxx
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltObject.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
TypeHandle FltObject::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltObject::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltObject::
FltObject(FltHeader *header) : FltBeadID(header) {
}
////////////////////////////////////////////////////////////////////
// Function: FltObject::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this bead based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltObject::
extract_record(FltRecordReader &reader) {
if (!FltBeadID::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_object, false);
DatagramIterator &iterator = reader.get_iterator();
_flags = iterator.get_be_uint32();
_relative_priority = iterator.get_be_int16();
_transparency = iterator.get_be_int16();
_special_id1 = iterator.get_be_int16();
_special_id2 = iterator.get_be_int16();
_significance = iterator.get_be_int16();
iterator.skip_bytes(2);
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltObject::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltObject::
build_record(FltRecordWriter &writer) const {
if (!FltBeadID::build_record(writer)) {
return false;
}
writer.set_opcode(FO_object);
Datagram &datagram = writer.update_datagram();
datagram.add_be_uint32(_flags);
datagram.add_be_int16(_relative_priority);
datagram.add_be_int16(_transparency);
datagram.add_be_int16(_special_id1);
datagram.add_be_int16(_special_id2);
datagram.add_be_int16(_significance);
datagram.pad_bytes(2);
return true;
}

View File

@ -0,0 +1,60 @@
// Filename: fltObject.h
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTOBJECT_H
#define FLTOBJECT_H
#include <pandatoolbase.h>
#include "fltBeadID.h"
////////////////////////////////////////////////////////////////////
// Class : FltObject
// Description : The main objecting bead of the flt file.
////////////////////////////////////////////////////////////////////
class FltObject : public FltBeadID {
public:
FltObject(FltHeader *header);
enum Flags {
F_no_daylight = 0x80000000,
F_no_dusk = 0x40000000,
F_no_night = 0x20000000,
F_no_illuminate = 0x10000000,
F_flat_shaded = 0x08000000,
F_shadow_object = 0x04000000,
};
unsigned int _flags;
int _relative_priority;
int _transparency;
int _special_id1, _special_id2;
int _significance;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltBeadID::init_type();
register_type(_type_handle, "FltObject",
FltBeadID::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#endif

View File

@ -0,0 +1,253 @@
// Filename: fltOpcode.cxx
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltOpcode.h"
ostream &
operator << (ostream &out, FltOpcode opcode) {
switch (opcode) {
case FO_none:
return out << "null opcode";
case FO_header:
return out << "header";
case FO_group:
return out << "group";
case FO_OB_scale:
case FO_OB_scale2:
case FO_OB_scale3:
return out << "(obsolete) scale";
case FO_object:
return out << "object";
case FO_face:
return out << "face";
case FO_OB_vertex_i:
return out << "(obsolete) vertex with ID";
case FO_OB_short_vertex:
return out << "(obsolete) short vertex";
case FO_OB_vertex_c:
return out << "(obsolete) vertex with color";
case FO_OB_vertex_cn:
return out << "(obsolete) vertex with color and normal";
case FO_push:
return out << "push";
case FO_pop:
return out << "pop";
case FO_OB_translate:
case FO_OB_translate2:
case FO_OB_translate3:
return out << "(obsolete) translate";
case FO_OB_dof:
return out << "(obsolete) degree-of-freedom";
case FO_dof:
return out << "degree-of-freedom";
case FO_OB_instance_ref:
return out << "(obsolete) instance reference";
case FO_OB_instance:
return out << "(obsolete) instance definition";
case FO_push_face:
return out << "push subface";
case FO_pop_face:
return out << "pop subface";
case FO_comment:
return out << "comment";
case FO_color_palette:
return out << "color palette";
case FO_long_id:
return out << "long ID";
case FO_transform_matrix:
return out << "transformation matrix";
case FO_OB_rotate_point:
case FO_OB_rotate_point2:
return out << "(obsolete) rotate about point";
case FO_OB_rotate_edge:
return out << "(obsolete) rotate about edge";
case FO_OB_nu_scale:
return out << "(obsolete) non-uniform scale";
case FO_OB_rotate_to_point:
return out << "(obsolete) rotate to point";
case FO_OB_put:
return out << "(obsolete) put";
case FO_OB_bounding_box:
return out << "(obsolete) bounding box";
case FO_vector:
return out << "vector";
case FO_bsp:
return out << "BSP";
case FO_replicate:
return out << "replicate";
case FO_instance_ref:
return out << "instance reference";
case FO_instance:
return out << "instance definition";
case FO_external_ref:
return out << "external reference";
case FO_texture:
return out << "texture";
case FO_OB_eyepoint_palette:
return out << "(obsolete) eyepoint palette";
case FO_14_material_palette:
return out << "v14 material palette";
case FO_vertex_palette:
return out << "vertex palette";
case FO_vertex_c:
return out << "vertex with color";
case FO_vertex_cn:
return out << "vertex with color and normal";
case FO_vertex_cnu:
return out << "vertex with color, normal, and uv";
case FO_vertex_cu:
return out << "vertex with color and uv";
case FO_vertex_list:
return out << "vertex list";
case FO_lod:
return out << "LOD";
case FO_bounding_box:
return out << "bounding box";
case FO_rotate_about_edge:
return out << "rotate about edge";
case FO_translate:
return out << "translate";
case FO_scale:
return out << "scale";
case FO_rotate_about_point:
return out << "rotate about point";
case FO_rotate_and_scale:
return out << "rotate and/or scale";
case FO_put:
return out << "put";
case FO_eyepoint_palette:
return out << "eyepoint palette";
case FO_road_segment:
return out << "road segment";
case FO_road_zone:
return out << "road zone";
case FO_morph_list:
return out << "morph vertex list";
case FO_behavior_palette:
return out << "behavior palette";
case FO_sound:
return out << "sound";
case FO_road_path:
return out << "road path";
case FO_sound_palette:
return out << "sound palette";
case FO_general_matrix:
return out << "general matrix";
case FO_text:
return out << "text";
case FO_switch:
return out << "switch";
case FO_line_style:
return out << "line style";
case FO_clip_region:
return out << "clip region";
case FO_light_source:
return out << "light source";
case FO_light_definition:
return out << "light source definition";
case FO_bounding_sphere:
return out << "bounding sphere";
case FO_bounding_cylinder:
return out << "bounding cylinder";
case FO_bv_center:
return out << "bounding volume center";
case FO_bv_orientation:
return out << "bounding volume orientation";
case FO_texture_map_palette:
return out << "texture mapping palette";
case FO_15_material:
return out << "material";
case FO_color_name_palette:
return out << "color name palette";
case FO_cat:
return out << "continuously adaptive terrain";
case FO_cat_data:
return out << "CAT Data";
case FO_push_attribute:
return out << "push attribute";
case FO_pop_attribute:
return out << "pop attribute";
default:
return out << "unknown opcode " << (int)opcode;
}
}

View File

@ -0,0 +1,101 @@
// Filename: fltOpcode.h
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTOPCODE_H
#define FLTOPCODE_H
#include <pandatoolbase.h>
// Known opcodes, as of the latest version of flt.
enum FltOpcode {
FO_none = 0,
FO_header = 1,
FO_group = 2,
FO_OB_scale = 3, // obsolete
FO_object = 4,
FO_face = 5,
FO_OB_vertex_i = 6, // obsolete
FO_OB_short_vertex = 7, // obsolete
FO_OB_vertex_c = 8, // obsolete
FO_OB_vertex_cn = 9, // obsolete
FO_push = 10,
FO_pop = 11,
FO_OB_translate = 12, // obsolete
FO_OB_dof = 13, // obsolete
FO_dof = 14,
FO_OB_instance_ref = 16, // obsolete
FO_OB_instance = 17, // obsolete
FO_push_face = 19,
FO_pop_face = 20,
FO_comment = 31,
FO_color_palette = 32,
FO_long_id = 33,
FO_OB_translate2 = 40, // obsolete
FO_OB_rotate_point = 41, // obsolete
FO_OB_rotate_edge = 42, // obsolete
FO_OB_scale2 = 43, // obsolete
FO_OB_translate3 = 44, // obsolete
FO_OB_nu_scale = 45, // obsolete
FO_OB_rotate_point2 = 46, // obsolete
FO_OB_rotate_to_point = 47, // obsolete
FO_OB_put = 48, // obsolete
FO_transform_matrix = 49,
FO_vector = 50,
FO_OB_bounding_box = 51, // obsolete
FO_bsp = 55,
FO_replicate = 60,
FO_instance_ref = 61,
FO_instance = 62,
FO_external_ref = 63,
FO_texture = 64,
FO_OB_eyepoint_palette = 65, // obsolete
FO_14_material_palette = 66,
FO_vertex_palette = 67,
FO_vertex_c = 68,
FO_vertex_cn = 69,
FO_vertex_cnu = 70,
FO_vertex_cu = 71,
FO_vertex_list = 72,
FO_lod = 73,
FO_bounding_box = 74,
FO_rotate_about_edge = 76,
FO_OB_scale3 = 77, // obsolete
FO_translate = 78,
FO_scale = 79,
FO_rotate_about_point = 80,
FO_rotate_and_scale = 81,
FO_put = 82,
FO_eyepoint_palette = 83,
FO_road_segment = 87,
FO_road_zone = 88,
FO_morph_list = 89,
FO_behavior_palette = 90,
FO_sound = 91,
FO_road_path = 92,
FO_sound_palette = 93,
FO_general_matrix = 94,
FO_text = 95,
FO_switch = 96,
FO_line_style = 97,
FO_clip_region = 98,
FO_light_source = 101,
FO_light_definition = 102,
FO_bounding_sphere = 105,
FO_bounding_cylinder = 106,
FO_bv_center = 108,
FO_bv_orientation = 109,
FO_texture_map_palette = 112,
FO_15_material = 113,
FO_color_name_palette = 114,
FO_cat = 115,
FO_cat_data = 116,
FO_push_attribute = 122,
FO_pop_attribute = 123,
};
ostream &operator << (ostream &out, FltOpcode opcode);
#endif

View File

@ -0,0 +1,47 @@
// Filename: fltPackedColor.I
// Created by: drose (25Aug00)
//
////////////////////////////////////////////////////////////////////
INLINE ostream &
operator << (ostream &out, const FltPackedColor &color) {
color.output(out);
return out;
}
////////////////////////////////////////////////////////////////////
// Function: FltPackedColor::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE FltPackedColor::
FltPackedColor() {
_a = 0;
_b = 0;
_g = 0;
_r = 0;
}
////////////////////////////////////////////////////////////////////
// Function: FltPackedColor::get_color
// Access: Public
// Description: Returns the four-component color as a Colorf, where
// each component is in the range [0, 1].
////////////////////////////////////////////////////////////////////
INLINE Colorf FltPackedColor::
get_color() const {
return Colorf(_r / 255.0, _g / 255.0, _b / 255.0, _a / 255.0);
}
////////////////////////////////////////////////////////////////////
// Function: FltPackedColor::get_rgb
// Access: Public
// Description: Returns the three-component color as an RGBColorf
// (ignoring the alpha component), where each component
// is in the range [0, 1].
////////////////////////////////////////////////////////////////////
INLINE RGBColorf FltPackedColor::
get_rgb() const {
return RGBColorf(_r / 255.0, _g / 255.0, _b / 255.0);
}

View File

@ -0,0 +1,52 @@
// Filename: fltPackedColor.cxx
// Created by: drose (25Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltPackedColor.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
////////////////////////////////////////////////////////////////////
// Function: FltPackedColor::output
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void FltPackedColor::
output(ostream &out) const {
out << "(" << _r << " " << _g << " " << _b << " " << _a << ")";
}
////////////////////////////////////////////////////////////////////
// Function: FltPackedColor::extract_record
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool FltPackedColor::
extract_record(FltRecordReader &reader) {
DatagramIterator &iterator = reader.get_iterator();
_a = iterator.get_uint8();
_g = iterator.get_uint8();
_b = iterator.get_uint8();
_r = iterator.get_uint8();
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltPackedColor::build_record
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool FltPackedColor::
build_record(FltRecordWriter &writer) const {
Datagram &datagram = writer.update_datagram();
datagram.add_uint8(_a);
datagram.add_uint8(_g);
datagram.add_uint8(_b);
datagram.add_uint8(_r);
return true;
}

View File

@ -0,0 +1,46 @@
// Filename: fltPackedColor.h
// Created by: drose (25Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTPACKEDCOLOR_H
#define FLTPACKEDCOLOR_H
#include <pandatoolbase.h>
#include <luse.h>
class FltRecordReader;
class FltRecordWriter;
////////////////////////////////////////////////////////////////////
// Class : FltPackedColor
// Description : A packed color record, A, B, G, R. This appears, for
// instance, within a face bead.
////////////////////////////////////////////////////////////////////
class FltPackedColor {
public:
INLINE FltPackedColor();
INLINE Colorf get_color() const;
INLINE RGBColorf get_rgb() const;
void output(ostream &out) const;
bool extract_record(FltRecordReader &reader);
bool build_record(FltRecordWriter &writer) const;
public:
int _a;
int _b;
int _g;
int _r;
};
INLINE ostream &operator << (ostream &out, const FltPackedColor &color);
#include "fltPackedColor.I"
#endif

View File

@ -0,0 +1,10 @@
// Filename: fltRecord.I
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
INLINE ostream &
operator << (ostream &out, const FltRecord &record) {
record.output(out);
return out;
}

View File

@ -0,0 +1,648 @@
// Filename: fltRecord.cxx
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltRecord.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
#include "fltHeader.h"
#include "fltGroup.h"
#include "fltObject.h"
#include "fltFace.h"
#include "fltVertexList.h"
#include "fltLOD.h"
#include "fltInstanceDefinition.h"
#include "fltInstanceRef.h"
#include "fltUnsupportedRecord.h"
#include "fltExternalReference.h"
#include <indent.h>
TypeHandle FltRecord::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltRecord::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltRecord::
FltRecord(FltHeader *header) :
_header(header)
{
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
FltRecord::
~FltRecord() {
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::get_num_children
// Access: Public
// Description: Returns the number of child records of this record. This
// reflects the normal scene graph hierarchy.
////////////////////////////////////////////////////////////////////
int FltRecord::
get_num_children() const {
return _children.size();
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::get_child
// Access: Public
// Description: Returns the nth child of this record.
////////////////////////////////////////////////////////////////////
FltRecord *FltRecord::
get_child(int n) const {
nassertr(n >= 0 && n < (int)_children.size(), (FltRecord *)NULL);
return _children[n];
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::clear_children
// Access: Public
// Description: Removes all children from this record.
////////////////////////////////////////////////////////////////////
void FltRecord::
clear_children() {
_children.clear();
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::add_child
// Access: Public
// Description: Adds a new child to the end of the list of children
// for this record.
////////////////////////////////////////////////////////////////////
void FltRecord::
add_child(FltRecord *child) {
_children.push_back(child);
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::get_num_subfaces
// Access: Public
// Description: Returns the number of subface records of this record.
// Normally, subfaces will only be present on object
// records, although it is logically possible for them to
// appear anywhere.
////////////////////////////////////////////////////////////////////
int FltRecord::
get_num_subfaces() const {
return _subfaces.size();
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::get_subface
// Access: Public
// Description: Returns the nth subface of this record.
////////////////////////////////////////////////////////////////////
FltRecord *FltRecord::
get_subface(int n) const {
nassertr(n >= 0 && n < (int)_subfaces.size(), (FltRecord *)NULL);
return _subfaces[n];
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::clear_subfaces
// Access: Public
// Description: Removes all subfaces from this record.
////////////////////////////////////////////////////////////////////
void FltRecord::
clear_subfaces() {
_subfaces.clear();
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::add_subface
// Access: Public
// Description: Adds a new subface to the end of the list of subfaces
// for this record.
////////////////////////////////////////////////////////////////////
void FltRecord::
add_subface(FltRecord *subface) {
_subfaces.push_back(subface);
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::get_num_ancillary
// Access: Public
// Description: Returns the number of unsupported ancillary records
// of this record. These are ancillary records that
// appeared following this record in the flt file but that
// aren't directly understood by the flt
// loader--normally, an ancillary record is examined and
// decoded on the spot, and no pointer to it is kept.
////////////////////////////////////////////////////////////////////
int FltRecord::
get_num_ancillary() const {
return _ancillary.size();
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::get_ancillary
// Access: Public
// Description: Returns the nth unsupported ancillary record of this
// record. See get_num_ancillary().
////////////////////////////////////////////////////////////////////
FltRecord *FltRecord::
get_ancillary(int n) const {
nassertr(n >= 0 && n < (int)_ancillary.size(), (FltRecord *)NULL);
return _ancillary[n];
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::clear_ancillary
// Access: Public
// Description: Removes all unsupported ancillary records from this
// record. See get_num_ancillary().
////////////////////////////////////////////////////////////////////
void FltRecord::
clear_ancillary() {
_ancillary.clear();
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::add_ancillary
// Access: Public
// Description: Adds a new unsupported ancillary record to the end of
// the list of ancillary records for this record. This
// record will be written to the flt file following this
// record, without attempting to understand what is in it.
//
// Normally, there is no reason to use this function; if
// the data stored in the FltRecord requires one or more
// ancillary record, the appropriate records will
// automatically be generated when the record is written.
// This function is only required to output a record
// whose type is not supported by the flt loader. But
// it would be better to extend the flt loader to know
// about this new kind of data record.
////////////////////////////////////////////////////////////////////
void FltRecord::
add_ancillary(FltRecord *ancillary) {
_ancillary.push_back(ancillary);
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::has_comment
// Access: Public
// Description: Returns true if this record has a nonempty comment,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool FltRecord::
has_comment() const {
return !_comment.empty();
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::get_comment
// Access: Public
// Description: Retrieves the comment for this record.
////////////////////////////////////////////////////////////////////
const string &FltRecord::
get_comment() const {
return _comment;
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::clear_comment
// Access: Public
// Description: Removes the comment for this record.
////////////////////////////////////////////////////////////////////
void FltRecord::
clear_comment() {
_comment = "";
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::set_comment
// Access: Public
// Description: Changes the comment for this record.
////////////////////////////////////////////////////////////////////
void FltRecord::
set_comment(const string &comment) {
_comment = comment;
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::output
// Access: Public
// Description: Writes a quick one-line description of the record, but
// not its children. This is a human-readable
// description, primarily for debugging; to write a flt
// file, use FltHeader::write_flt().
////////////////////////////////////////////////////////////////////
void FltRecord::
output(ostream &out) const {
out << get_type();
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::write
// Access: Public
// Description: Writes a multiple-line description of the record and
// all of its children. This is a human-readable
// description, primarily for debugging; to write a flt
// file, use FltHeader::write_flt().
////////////////////////////////////////////////////////////////////
void FltRecord::
write(ostream &out, int indent_level) const {
indent(out, indent_level) << *this;
write_children(out, indent_level);
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::write_children
// Access: Protected
// Description: Assuming the current write position has been left at
// the end of the last line of the record description,
// writes out the list of children.
////////////////////////////////////////////////////////////////////
void FltRecord::
write_children(ostream &out, int indent_level) const {
if (!_ancillary.empty()) {
out << " + " << _ancillary.size() << " ancillary";
}
if (!_subfaces.empty()) {
out << " [";
Records::const_iterator ci;
for (ci = _subfaces.begin(); ci != _subfaces.end(); ++ci) {
out << " " << *(*ci);
}
out << " ]";
}
if (!_children.empty()) {
out << " {\n";
Records::const_iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
(*ci)->write(out, indent_level + 2);
}
indent(out, indent_level) << "}\n";
} else {
out << "\n";
}
}
/*
virtual void write(ostream &out) const;
virtual void build_record(Datagram &datagram) const;
*/
////////////////////////////////////////////////////////////////////
// Function: FltRecord::is_ancillary
// Access: Protected, Static
// Description: Returns true if the indicated opcode corresponds to
// an ancillary record type, false otherwise. In
// general, this function is used to identify ancillary
// records that are not presently supported by the
// FltReader; these will be ignored. Normally,
// ancillary records will be detected and processed by
// extract_ancillary().
////////////////////////////////////////////////////////////////////
bool FltRecord::
is_ancillary(FltOpcode opcode) {
switch (opcode) {
case FO_comment:
case FO_long_id:
case FO_replicate:
case FO_road_zone:
case FO_transform_matrix:
case FO_rotate_about_edge:
case FO_translate:
case FO_scale:
case FO_rotate_about_point:
case FO_rotate_and_scale:
case FO_put:
case FO_general_matrix:
case FO_vector:
case FO_bounding_box:
case FO_bounding_sphere:
case FO_bounding_cylinder:
case FO_bv_center:
case FO_bv_orientation:
case FO_vertex_palette:
case FO_vertex_c:
case FO_vertex_cn:
case FO_vertex_cnu:
case FO_vertex_cu:
case FO_color_palette:
case FO_color_name_palette:
case FO_15_material:
case FO_texture:
case FO_eyepoint_palette:
case FO_light_definition:
return true;
case FO_header:
case FO_group:
case FO_object:
case FO_face:
case FO_dof:
case FO_vertex_list:
case FO_morph_list:
case FO_bsp:
case FO_external_ref:
case FO_lod:
case FO_sound:
case FO_light_source:
case FO_road_segment:
case FO_road_path:
case FO_clip_region:
case FO_text:
case FO_switch:
return false;
case FO_push:
case FO_pop:
case FO_push_face:
case FO_pop_face:
case FO_push_attribute:
case FO_pop_attribute:
case FO_instance:
case FO_instance_ref:
return false;
default:
nout << "Don't know whether " << opcode << " is ancillary.\n";
return false;
}
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::create_new_record
// Access: Protected
// Description: Creates a new FltRecord corresponding to the opcode.
// If the opcode is unknown, creates a
// FltUnsupportedRecord.
////////////////////////////////////////////////////////////////////
FltRecord *FltRecord::
create_new_record(FltOpcode opcode) const {
switch (opcode) {
case FO_group:
return new FltGroup(_header);
case FO_object:
return new FltObject(_header);
case FO_face:
return new FltFace(_header);
case FO_vertex_list:
return new FltVertexList(_header);
case FO_lod:
return new FltLOD(_header);
case FO_instance:
return new FltInstanceDefinition(_header);
case FO_instance_ref:
return new FltInstanceRef(_header);
case FO_external_ref:
return new FltExternalReference(_header);
default:
nout << "Unsupported record " << opcode << "\n";
return new FltUnsupportedRecord(_header);
}
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::read_record_and_children
// Access: Protected
// Description: Extracts this record information from the current
// record presented in the reader, then advances the
// reader and continues to read any children, if
// present. On return, the reader is position on the
// next sibling record to this record.
//
// Returns FE_ok if successful, otherwise on error.
////////////////////////////////////////////////////////////////////
FltError FltRecord::
read_record_and_children(FltRecordReader &reader) {
if (!extract_record(reader)) {
nout << "Could not extract record for " << *this << "\n";
return FE_invalid_record;
}
FltError result = reader.advance();
if (result == FE_end_of_file) {
return FE_ok;
} else if (result != FE_ok) {
return result;
}
while (true) {
if (extract_ancillary(reader)) {
// Ok, a known ancillary record. Fine.
} else if (reader.get_opcode() == FO_push) {
// A push begins a new list of children.
result = reader.advance();
if (result != FE_ok) {
return result;
}
while (reader.get_opcode() != FO_pop) {
PT(FltRecord) child = create_new_record(reader.get_opcode());
FltError result = child->read_record_and_children(reader);
if (result != FE_ok) {
return result;
}
if (child->is_of_type(FltInstanceDefinition::get_class_type())) {
// A special case for an instance definition. These
// shouldn't appear in the hierarchy, but should instead be
// added directly to the header.
_header->add_instance(DCAST(FltInstanceDefinition, child));
} else {
add_child(child);
}
if (reader.eof() || reader.error()) {
return FE_end_of_file;
}
}
} else if (reader.get_opcode() == FO_push_face) {
// A push subface begins a new list of subfaces.
result = reader.advance();
if (result != FE_ok) {
return result;
}
while (reader.get_opcode() != FO_pop_face) {
PT(FltRecord) subface = create_new_record(reader.get_opcode());
FltError result = subface->read_record_and_children(reader);
if (result != FE_ok) {
return result;
}
add_subface(subface);
if (reader.eof() || reader.error()) {
return FE_end_of_file;
}
}
} else if (is_ancillary(reader.get_opcode())) {
// An unsupported ancillary record. Skip it.
PT(FltRecord) ancillary = create_new_record(reader.get_opcode());
ancillary->extract_record(reader);
_ancillary.push_back(ancillary);
} else {
// None of the above: we're done.
return FE_ok;
}
// Skip to the next record. If that's the end, fine.
result = reader.advance();
if (result == FE_end_of_file) {
return FE_ok;
} else if (result != FE_ok) {
return result;
}
}
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this record based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltRecord::
extract_record(FltRecordReader &) {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::extract_ancillary
// Access: Protected, Virtual
// Description: Checks whether the given record, which follows this
// record sequentially in the file, is an ancillary record
// of this record. If it is, extracts the relevant
// information and returns true; otherwise, leaves it
// alone and returns false.
////////////////////////////////////////////////////////////////////
bool FltRecord::
extract_ancillary(FltRecordReader &reader) {
if (reader.get_opcode() == FO_comment) {
_comment = reader.get_iterator().get_remaining_bytes();
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::write_record_and_children
// Access: Protected, Virtual
// Description: Writes this record out to the flt file, along with all
// of its ancillary records and children records. Returns
// FE_ok on success, or something else on error.
////////////////////////////////////////////////////////////////////
FltError FltRecord::
write_record_and_children(FltRecordWriter &writer) const {
// First, write the record.
if (!build_record(writer)) {
return FE_bad_data;
}
FltError result = writer.advance();
if (result != FE_ok) {
return result;
}
// Then the ancillary data.
result = write_ancillary(writer);
if (result != FE_ok) {
return result;
}
Records::const_iterator ci;
for (ci = _ancillary.begin(); ci != _ancillary.end(); ++ci) {
if (!(*ci)->build_record(writer)) {
return FE_bad_data;
}
result = writer.advance();
if (result != FE_ok) {
return result;
}
}
// Any subfaces?
if (!_subfaces.empty()) {
result = writer.write_record(FO_push_face);
if (result != FE_ok) {
return result;
}
for (ci = _subfaces.begin(); ci != _subfaces.end(); ++ci) {
(*ci)->write_record_and_children(writer);
}
result = writer.write_record(FO_pop_face);
if (result != FE_ok) {
return result;
}
}
// Finally, write all the children.
if (!_children.empty()) {
result = writer.write_record(FO_push);
if (result != FE_ok) {
return result;
}
for (ci = _children.begin(); ci != _children.end(); ++ci) {
(*ci)->write_record_and_children(writer);
}
result = writer.write_record(FO_pop);
if (result != FE_ok) {
return result;
}
}
return FE_ok;
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltRecord::
build_record(FltRecordWriter &) const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::write_ancillary
// Access: Protected, Virtual
// Description: Writes whatever ancillary records are required for
// this record. Returns FE_ok on success, or something
// else if there is some error.
////////////////////////////////////////////////////////////////////
FltError FltRecord::
write_ancillary(FltRecordWriter &writer) const {
if (!_comment.empty()) {
Datagram dc(_comment);
FltError result = writer.write_record(FO_comment, dc);
if (result != FE_ok) {
return result;
}
}
return FE_ok;
}

View File

@ -0,0 +1,108 @@
// filename: fltRecord.h
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTRECORD_H
#define FLTRECORD_H
#include <pandatoolbase.h>
#include "fltOpcode.h"
#include "fltError.h"
#include <typeHandle.h>
#include <typedReferenceCount.h>
#include <pointerTo.h>
class FltHeader;
class FltRecordReader;
class FltRecordWriter;
////////////////////////////////////////////////////////////////////
// Class : FltRecord
// Description : The base class for all kinds of records in a MultiGen
// OpenFlight file. A flt file consists of a hierarchy
// of "beads" of various kinds, each of which may be
// followed by n ancillary records, written sequentially
// to the file.
////////////////////////////////////////////////////////////////////
class FltRecord : public TypedReferenceCount {
public:
FltRecord(FltHeader *header);
virtual ~FltRecord();
int get_num_children() const;
FltRecord *get_child(int n) const;
void clear_children();
void add_child(FltRecord *child);
int get_num_subfaces() const;
FltRecord *get_subface(int n) const;
void clear_subfaces();
void add_subface(FltRecord *subface);
int get_num_ancillary() const;
FltRecord *get_ancillary(int n) const;
void clear_ancillary();
void add_ancillary(FltRecord *ancillary);
bool has_comment() const;
const string &get_comment() const;
void clear_comment();
void set_comment(const string &comment);
virtual void output(ostream &out) const;
virtual void write(ostream &out, int indent_level = 0) const;
protected:
void write_children(ostream &out, int indent_level) const;
static bool is_ancillary(FltOpcode opcode);
FltRecord *create_new_record(FltOpcode opcode) const;
FltError read_record_and_children(FltRecordReader &reader);
virtual bool extract_record(FltRecordReader &reader);
virtual bool extract_ancillary(FltRecordReader &reader);
virtual FltError write_record_and_children(FltRecordWriter &writer) const;
virtual bool build_record(FltRecordWriter &writer) const;
virtual FltError write_ancillary(FltRecordWriter &writer) const;
protected:
FltHeader *_header;
private:
typedef vector<PT(FltRecord)> Records;
Records _children;
Records _subfaces;
Records _ancillary;
string _comment;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedReferenceCount::init_type();
register_type(_type_handle, "FltRecord",
TypedReferenceCount::get_class_type());
}
private:
static TypeHandle _type_handle;
};
INLINE ostream &operator << (ostream &out, const FltRecord &record);
#include "fltRecord.I"
#endif

View File

@ -0,0 +1,176 @@
// Filename: fltRecordReader.cxx
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltRecordReader.h"
#include <datagramIterator.h>
////////////////////////////////////////////////////////////////////
// Function: FltRecordReader::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltRecordReader::
FltRecordReader(istream &in) :
_in(in)
{
_opcode = FO_none;
_record_length = 0;
_iterator = (DatagramIterator *)NULL;
_state = S_begin;
}
////////////////////////////////////////////////////////////////////
// Function: FltRecordReader::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltRecordReader::
~FltRecordReader() {
if (_iterator != (DatagramIterator *)NULL) {
delete _iterator;
_iterator = (DatagramIterator *)NULL;
}
}
////////////////////////////////////////////////////////////////////
// Function: FltRecordReader::get_opcode
// Access: Public
// Description: Returns the opcode associated with the current
// record.
////////////////////////////////////////////////////////////////////
FltOpcode FltRecordReader::
get_opcode() const {
nassertr(_state == S_normal, FO_none);
return _opcode;
}
////////////////////////////////////////////////////////////////////
// Function: FltRecordReader::get_iterator
// Access: Public
// Description: Returns an iterator suitable for extracting data from
// the current record.
////////////////////////////////////////////////////////////////////
DatagramIterator &FltRecordReader::
get_iterator() {
nassertr(_state == S_normal, *_iterator);
return *_iterator;
}
////////////////////////////////////////////////////////////////////
// Function: FltRecordReader::get_datagram
// Access: Public
// Description: Returns the datagram representing the entire record,
// less the four-byte header.
////////////////////////////////////////////////////////////////////
const Datagram &FltRecordReader::
get_datagram() {
#ifndef NDEBUG
static Datagram bogus_datagram;
nassertr(_state == S_normal, bogus_datagram);
#endif
return _iterator->get_datagram();
}
////////////////////////////////////////////////////////////////////
// Function: FltRecordReader::get_record_length
// Access: Public
// Description: Returns the entire length of the record, including
// the four-byte header.
////////////////////////////////////////////////////////////////////
int FltRecordReader::
get_record_length() const {
return _record_length;
}
////////////////////////////////////////////////////////////////////
// Function: FltRecordReader::advance
// Access: Public
// Description: Extracts the next record from the file. Returns true
// if there is another record, or false if the end of
// file has been reached.
////////////////////////////////////////////////////////////////////
FltError FltRecordReader::
advance() {
if (_state == S_eof) {
return FE_end_of_file;
}
if (_state == S_error) {
return FE_read_error;
}
if (_iterator != (DatagramIterator *)NULL) {
delete _iterator;
_iterator = (DatagramIterator *)NULL;
}
// Get the first four bytes of the record. This will be the opcode
// and length.
static const int header_size = 4;
char bytes[header_size];
_in.read(bytes, header_size);
if (_in.eof()) {
_state = S_eof;
return FE_end_of_file;
} else if (_in.fail()) {
_state = S_error;
return FE_read_error;
}
// Now extract out the opcode and length.
Datagram dg(bytes, header_size);
DatagramIterator dgi(dg);
_opcode = (FltOpcode)dgi.get_be_int16();
_record_length = dgi.get_be_uint16();
// cerr << "Reading " << _opcode << " of length " << _record_length << "\n";
// And now read the full record based on the length.
int length = _record_length - header_size;
char *buffer = new char[length];
_in.read(buffer, length);
_datagram = Datagram(buffer, length);
delete[] buffer;
if (_in.eof()) {
_state = S_eof;
return FE_end_of_file;
}
if (_in.fail()) {
_state = S_error;
return FE_read_error;
}
// Finally, create a new iterator to read this record.
_iterator = new DatagramIterator(_datagram);
_state = S_normal;
return FE_ok;
}
////////////////////////////////////////////////////////////////////
// Function: FltRecordReader::eof
// Access: Public
// Description: Returns true if end-of-file has been reached without
// error.
////////////////////////////////////////////////////////////////////
bool FltRecordReader::
eof() const {
return _state == S_eof;
}
////////////////////////////////////////////////////////////////////
// Function: FltRecordReader::error
// Access: Public
// Description: Returns true if some error has been encountered while
// reading (for instance, a truncated file).
////////////////////////////////////////////////////////////////////
bool FltRecordReader::
error() const {
return _state == S_error;
}

View File

@ -0,0 +1,58 @@
// Filename: fltRecordReader.h
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTRECORDREADER_H
#define FLTRECORDREADER_H
#include <pandatoolbase.h>
#include "fltOpcode.h"
#include "fltError.h"
#include <datagram.h>
#include <datagramIterator.h>
////////////////////////////////////////////////////////////////////
// Class : FltRecordReader
// Description : This class turns an istream into a sequence of
// FltRecords by reading a sequence of Datagrams and
// extracting the opcode from each one. It remembers
// where it is in the file and what the current record
// is.
////////////////////////////////////////////////////////////////////
class FltRecordReader {
public:
FltRecordReader(istream &in);
~FltRecordReader();
FltOpcode get_opcode() const;
DatagramIterator &get_iterator();
const Datagram &get_datagram();
int get_record_length() const;
FltError advance();
bool eof() const;
bool error() const;
private:
istream &_in;
Datagram _datagram;
FltOpcode _opcode;
int _record_length;
DatagramIterator *_iterator;
enum State {
S_begin,
S_normal,
S_eof,
S_error
};
State _state;
};
#endif

View File

@ -0,0 +1,140 @@
// Filename: fltRecordWriter.cxx
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltRecordWriter.h"
#include "fltInstanceDefinition.h"
#include "fltHeader.h"
#include <datagram.h>
////////////////////////////////////////////////////////////////////
// Function: FltRecordWriter::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltRecordWriter::
FltRecordWriter(ostream &out) :
_out(out)
{
}
////////////////////////////////////////////////////////////////////
// Function: FltRecordWriter::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltRecordWriter::
~FltRecordWriter() {
}
////////////////////////////////////////////////////////////////////
// Function: FltRecordWriter::set_opcode
// Access: Public
// Description: Sets the opcode associated with the current record.
////////////////////////////////////////////////////////////////////
void FltRecordWriter::
set_opcode(FltOpcode opcode) {
_opcode = opcode;
}
////////////////////////////////////////////////////////////////////
// Function: FltRecordWriter::set_datagram
// Access: Public
// Description: Sets the datagram that will be written when advance()
// is called.
////////////////////////////////////////////////////////////////////
void FltRecordWriter::
set_datagram(const Datagram &datagram) {
_datagram = datagram;
}
////////////////////////////////////////////////////////////////////
// Function: FltRecordWriter::update_datagram
// Access: Public
// Description: Returns a modifiable reference to the datagram
// associated with the current record. This datagram
// should then be stuffed with data corresponding to the
// data in the record, in preparation for calling
// advance() to write the data.
////////////////////////////////////////////////////////////////////
Datagram &FltRecordWriter::
update_datagram() {
return _datagram;
}
////////////////////////////////////////////////////////////////////
// Function: FltRecordWriter::advance
// Access: Public
// Description: Writes the current record to the flt file, and resets
// the current record to receive new data. Returns
// FE_ok on success, or something else on error.
////////////////////////////////////////////////////////////////////
FltError FltRecordWriter::
advance() {
// cerr << "Writing " << _opcode << " of length " << _datagram.get_length() << "\n";
// Build a mini-datagram to write the header.
static const int header_size = 4;
Datagram dg;
dg.add_be_int16(_opcode);
dg.add_be_int16(_datagram.get_length() + header_size);
nassertr(dg.get_length() == header_size, FE_internal);
_out.write(dg.get_message().data(), dg.get_length());
if (_out.fail()) {
return FE_write_error;
}
// Now write the rest of the record.
_out.write(_datagram.get_message().data(), _datagram.get_length());
if (_out.fail()) {
return FE_write_error;
}
_datagram.clear();
_opcode = FO_none;
return FE_ok;
}
////////////////////////////////////////////////////////////////////
// Function: FltRecordWriter::write_record
// Access: Public
// Description: A convenience function to quickly write a simple
// record that consists of an opcode and possibly a
// datagram.
////////////////////////////////////////////////////////////////////
FltError FltRecordWriter::
write_record(FltOpcode opcode, const Datagram &datagram) {
_opcode = opcode;
_datagram = datagram;
return advance();
}
////////////////////////////////////////////////////////////////////
// Function: FltRecordWriter::write_instance_def
// Access: Public
// Description: Ensures that the given instance definition has
// already been written to the file. If it has not,
// writes it now.
////////////////////////////////////////////////////////////////////
FltError FltRecordWriter::
write_instance_def(FltHeader *header, int instance_index) {
bool inserted = _instances_written.insert(instance_index).second;
if (!inserted) {
// It's already been written.
return FE_ok;
}
FltInstanceDefinition *instance = header->get_instance(instance_index);
if (instance == (FltInstanceDefinition *)NULL) {
return FE_undefined_instance;
}
return instance->write_record_and_children(*this);
}

View File

@ -0,0 +1,51 @@
// Filename: fltRecordWriter.h
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTRECORDWRITER_H
#define FLTRECORDWRITER_H
#include <pandatoolbase.h>
#include "fltOpcode.h"
#include "fltError.h"
#include <datagram.h>
class FltHeader;
////////////////////////////////////////////////////////////////////
// Class : FltRecordWriter
// Description : This class writes a sequence of FltRecords to an
// ostream, handling opcode and size counts properly.
////////////////////////////////////////////////////////////////////
class FltRecordWriter {
public:
FltRecordWriter(ostream &out);
~FltRecordWriter();
void set_opcode(FltOpcode opcode);
const Datagram &get_datagram() const;
void set_datagram(const Datagram &datagram);
Datagram &update_datagram();
FltError advance();
FltError write_record(FltOpcode opcode,
const Datagram &datagram = Datagram());
FltError write_instance_def(FltHeader *header, int instance_index);
private:
ostream &_out;
Datagram _datagram;
FltOpcode _opcode;
typedef set<int> Instances;
Instances _instances_written;
};
#endif

View File

@ -0,0 +1,431 @@
// Filename: fltTexture.cxx
// Created by: drose (25Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltTexture.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
#include "fltHeader.h"
TypeHandle FltTexture::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltTexture::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltTexture::
FltTexture(FltHeader *header) : FltRecord(header) {
_pattern_index = 0;
_x_location = 0;
_y_location = 0;
_num_texels_u = 0;
_num_texels_v = 0;
_real_world_size_u = 0;
_real_world_size_v = 0;
_up_vector_x = 0;
_up_vector_y = 1;
_file_format = FF_none;
_min_filter = MN_point;
_mag_filter = MG_point;
_repeat = RT_repeat;
_repeat_u = RT_repeat;
_repeat_v = RT_repeat;
_modify_flag = 0;
_x_pivot_point = 0;
_y_pivot_point = 0;
_env_type = ET_modulate;
_intensity_is_alpha = false;
_float_real_world_size_u = 0.0;
_float_real_world_size_v = 0.0;
_imported_origin_code = 0;
_kernel_version = 1520;
_internal_format = IF_default;
_external_format = EF_default;
_use_mipmap_kernel = false;
memset(_mipmap_kernel, 0, sizeof(_mipmap_kernel));
_use_lod_scale = false;
memset(_lod_scale, 0, sizeof(_lod_scale));
_clamp = 0.0;
_mag_filter_alpha = MG_point;
_mag_filter_color = MG_point;
_lambert_conic_central_meridian = 0.0;
_lambert_conic_upper_latitude = 0.0;
_lambert_conic_lower_latitude = 0.0;
_use_detail = false;
_detail_j = 0;
_detail_k = 0;
_detail_m = 0;
_detail_n = 0;
_detail_scramble = 0;
_use_tile = false;
_tile_lower_left_u = 0.0;
_tile_lower_left_v = 0.0;
_tile_upper_right_u = 0.0;
_tile_upper_right_v = 0.0;
_projection = PT_flat_earth;
_earth_model = EM_wgs84;
_utm_zone = 0;
_image_origin = IO_lower_left;
_geospecific_points_units = PU_degrees;
_geospecific_hemisphere = H_southern;
_file_version = 1501;
}
////////////////////////////////////////////////////////////////////
// Function: FltTexture::get_texture_filename
// Access: Public
// Description: Returns the name of the texture image file. If it
// appears to be a relative filename, it will be
// converted to the correct full pathname according to
// the texture_path specified in the header.
////////////////////////////////////////////////////////////////////
Filename FltTexture::
get_texture_filename() const {
Filename file(_filename);
file.resolve_filename(_header->get_texture_path());
return file;
}
////////////////////////////////////////////////////////////////////
// Function: FltTexture::get_attr_filename
// Access: Public
// Description: Returns the name of the texture's associated .attr
// file. This contains some additional MultiGen
// information about the texture parameters. This is,
// of course, just the name of the texture with .attr
// appended.
//
// Normally, it won't be necessary to access this file
// directly; you can call read_attr_data() or
// write_attr_data() to get at the data stored in this
// file. (And read_attr_data() is called automatically
// when the Flt file is read in.)
////////////////////////////////////////////////////////////////////
Filename FltTexture::
get_attr_filename() const {
string texture_filename = get_texture_filename();
return Filename::binary_filename(texture_filename + ".attr");
}
////////////////////////////////////////////////////////////////////
// Function: FltTexture::read_attr_data
// Access: Public
// Description: Opens up the texture's .attr file and reads its data
// into the extra FltTexture fields. This is normally
// performed automatically when the Flt file is read
// from disk.
////////////////////////////////////////////////////////////////////
FltError FltTexture::
read_attr_data() {
Filename attr_filename = get_attr_filename();
ifstream attr;
if (!attr_filename.open_read(attr)) {
return FE_could_not_open;
}
// Determine the file's size so we can read it all into one big
// datagram.
attr.seekg(0, ios::end);
if (attr.fail()) {
return FE_read_error;
}
streampos length = attr.tellg();
char *buffer = new char[length];
attr.seekg(0, ios::beg);
attr.read(buffer, length);
if (attr.fail()) {
return FE_read_error;
}
Datagram datagram(buffer, length);
delete[] buffer;
return unpack_attr(datagram);
}
////////////////////////////////////////////////////////////////////
// Function: FltTexture::write_attr_data
// Access: Public
// Description: Writes the texture's .attr file. This may or may
// not be performed automatically, according to the
// setting of FltHeader::set_auto_attr_update().
////////////////////////////////////////////////////////////////////
FltError FltTexture::
write_attr_data() const {
Datagram datagram;
FltError result = pack_attr(datagram);
if (result != FE_ok) {
return result;
}
Filename attr_filename = get_attr_filename();
ofstream attr;
if (!attr_filename.open_write(attr)) {
return FE_could_not_open;
}
attr.write((const char *)datagram.get_data(), datagram.get_length());
if (attr.fail()) {
return FE_write_error;
}
return FE_ok;
}
////////////////////////////////////////////////////////////////////
// Function: FltTexture::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this record based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltTexture::
extract_record(FltRecordReader &reader) {
if (!FltRecord::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_texture, false);
DatagramIterator &iterator = reader.get_iterator();
_filename = iterator.get_fixed_string(200);
_pattern_index = iterator.get_be_int32();
_x_location = iterator.get_be_int32();
_y_location = iterator.get_be_int32();
if (read_attr_data() != FE_ok) {
nout << "Unable to read attribute file " << get_attr_filename() << "\n";
}
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltTexture::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltTexture::
build_record(FltRecordWriter &writer) const {
if (!FltRecord::build_record(writer)) {
return false;
}
writer.set_opcode(FO_texture);
Datagram &datagram = writer.update_datagram();
datagram.add_fixed_string(_filename, 200);
datagram.add_be_int32(_pattern_index);
datagram.add_be_int32(_x_location);
datagram.add_be_int32(_y_location);
if (_header->get_auto_attr_update() == FltHeader::AU_always ||
(_header->get_auto_attr_update() == FltHeader::AU_if_missing &&
!get_attr_filename().exists())) {
if (write_attr_data() != FE_ok) {
nout << "Unable to write attribute file " << get_attr_filename() << "\n";
}
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltTexture::unpack_attr
// Access: Private
// Description: Reads the data from the attribute file.
////////////////////////////////////////////////////////////////////
FltError FltTexture::
unpack_attr(const Datagram &datagram) {
DatagramIterator iterator(datagram);
_num_texels_u = iterator.get_be_int32();
_num_texels_v = iterator.get_be_int32();
_real_world_size_u = iterator.get_be_int32();
_real_world_size_v = iterator.get_be_int32();
_up_vector_x = iterator.get_be_int32();
_up_vector_y = iterator.get_be_int32();
_file_format = (FileFormat)iterator.get_be_int32();
_min_filter = (Minification)iterator.get_be_int32();
_mag_filter = (Magnification)iterator.get_be_int32();
_repeat = (RepeatType)iterator.get_be_int32();
_repeat_u = (RepeatType)iterator.get_be_int32();
_repeat_v = (RepeatType)iterator.get_be_int32();
_modify_flag = iterator.get_be_int32();
_x_pivot_point = iterator.get_be_int32();
_y_pivot_point = iterator.get_be_int32();
_env_type = (EnvironmentType)iterator.get_be_int32();
_intensity_is_alpha = (iterator.get_be_int32() != 0);
iterator.skip_bytes(4 * 8);
iterator.skip_bytes(4); // Undocumented padding.
_float_real_world_size_u = iterator.get_be_float64();
_float_real_world_size_v = iterator.get_be_float64();
_imported_origin_code = iterator.get_be_int32();
_kernel_version = iterator.get_be_int32();
_internal_format = (InternalFormat)iterator.get_be_int32();
_external_format = (ExternalFormat)iterator.get_be_int32();
_use_mipmap_kernel = (iterator.get_be_int32() != 0);
int i;
for (i = 0; i < 8; i++) {
_mipmap_kernel[i] = iterator.get_be_float32();
}
_use_lod_scale = (iterator.get_be_int32() != 0);
for (i = 0; i < 8; i++) {
_lod_scale[i]._lod = iterator.get_be_float32();
_lod_scale[i]._scale = iterator.get_be_float32();
}
_clamp = iterator.get_be_float32();
_mag_filter_alpha = (Magnification)iterator.get_be_int32();
_mag_filter_color = (Magnification)iterator.get_be_int32();
iterator.skip_bytes(4 + 4 * 8);
_lambert_conic_central_meridian = iterator.get_be_float64();
_lambert_conic_upper_latitude = iterator.get_be_float64();
_lambert_conic_lower_latitude = iterator.get_be_float64();
iterator.skip_bytes(8 + 4 * 5);
_use_detail = (iterator.get_be_int32() != 0);
_detail_j = iterator.get_be_int32();
_detail_k = iterator.get_be_int32();
_detail_m = iterator.get_be_int32();
_detail_n = iterator.get_be_int32();
_detail_scramble = iterator.get_be_int32();
_use_tile = (iterator.get_be_int32() != 0);
_tile_lower_left_u = iterator.get_be_float32();
_tile_lower_left_v = iterator.get_be_float32();
_tile_upper_right_u = iterator.get_be_float32();
_tile_upper_right_v = iterator.get_be_float32();
_projection = (ProjectionType)iterator.get_be_int32();
_earth_model = (EarthModel)iterator.get_be_int32();
iterator.skip_bytes(4);
_utm_zone = iterator.get_be_int32();
_image_origin = (ImageOrigin)iterator.get_be_int32();
_geospecific_points_units = (PointsUnits)iterator.get_be_int32();
_geospecific_hemisphere = (Hemisphere)iterator.get_be_int32();
iterator.skip_bytes(4 + 4 + 149 * 4);
iterator.skip_bytes(8); // Undocumented padding.
_comment = iterator.get_fixed_string(512);
iterator.skip_bytes(13 * 4);
iterator.skip_bytes(4); // Undocumented padding.
_file_version = iterator.get_be_int32();
// Now read the geospecific control points.
_geospecific_control_points.clear();
int num_points = iterator.get_be_int32();
if (num_points > 0) {
iterator.skip_bytes(4);
while (num_points > 0) {
GeospecificControlPoint gcp;
gcp._uv[0] = iterator.get_be_float64();
gcp._uv[1] = iterator.get_be_float64();
gcp._real_earth[0] = iterator.get_be_float64();
gcp._real_earth[1] = iterator.get_be_float64();
}
}
nassertr(iterator.get_remaining_size() == 0, FE_ok);
return FE_ok;
}
////////////////////////////////////////////////////////////////////
// Function: FltTexture::pack_attr
// Access: Private
// Description: Packs the attribute data into a big datagram.
////////////////////////////////////////////////////////////////////
FltError FltTexture::
pack_attr(Datagram &datagram) const {
datagram.add_be_int32(_num_texels_u);
datagram.add_be_int32(_num_texels_v);
datagram.add_be_int32(_real_world_size_u);
datagram.add_be_int32(_real_world_size_v);
datagram.add_be_int32(_up_vector_x);
datagram.add_be_int32(_up_vector_y);
datagram.add_be_int32(_file_format);
datagram.add_be_int32(_min_filter);
datagram.add_be_int32(_mag_filter);
datagram.add_be_int32(_repeat);
datagram.add_be_int32(_repeat_u);
datagram.add_be_int32(_repeat_v);
datagram.add_be_int32(_modify_flag);
datagram.add_be_int32(_x_pivot_point);
datagram.add_be_int32(_y_pivot_point);
datagram.add_be_int32(_env_type);
datagram.add_be_int32(_intensity_is_alpha);
datagram.pad_bytes(4 * 8);
datagram.pad_bytes(4); // Undocumented padding.
datagram.add_be_float64(_float_real_world_size_u);
datagram.add_be_float64(_float_real_world_size_v);
datagram.add_be_int32(_imported_origin_code);
datagram.add_be_int32(_kernel_version);
datagram.add_be_int32(_internal_format);
datagram.add_be_int32(_external_format);
datagram.add_be_int32(_use_mipmap_kernel);
int i;
for (i = 0; i < 8; i++) {
datagram.add_be_float32(_mipmap_kernel[i]);
}
datagram.add_be_int32(_use_lod_scale);
for (i = 0; i < 8; i++) {
datagram.add_be_float32(_lod_scale[i]._lod);
datagram.add_be_float32(_lod_scale[i]._scale);
}
datagram.add_be_float32(_clamp);
datagram.add_be_int32(_mag_filter_alpha);
datagram.add_be_int32(_mag_filter_color);
datagram.pad_bytes(4 + 4 * 8);
datagram.add_be_float64(_lambert_conic_central_meridian);
datagram.add_be_float64(_lambert_conic_upper_latitude);
datagram.add_be_float64(_lambert_conic_lower_latitude);
datagram.pad_bytes(8 + 4 * 5);
datagram.add_be_int32(_use_detail);
datagram.add_be_int32(_detail_j);
datagram.add_be_int32(_detail_k);
datagram.add_be_int32(_detail_m);
datagram.add_be_int32(_detail_n);
datagram.add_be_int32(_detail_scramble);
datagram.add_be_int32(_use_tile);
datagram.add_be_float32(_tile_lower_left_u);
datagram.add_be_float32(_tile_lower_left_v);
datagram.add_be_float32(_tile_upper_right_u);
datagram.add_be_float32(_tile_upper_right_v);
datagram.add_be_int32(_projection);
datagram.add_be_int32(_earth_model);
datagram.pad_bytes(4);
datagram.add_be_int32(_utm_zone);
datagram.add_be_int32(_image_origin);
datagram.add_be_int32(_geospecific_points_units);
datagram.add_be_int32(_geospecific_hemisphere);
datagram.pad_bytes(4 + 4 + 149 * 4);
datagram.pad_bytes(8); // Undocumented padding.
datagram.add_fixed_string(_comment, 512);
datagram.pad_bytes(13 * 4);
datagram.pad_bytes(4); // Undocumented padding.
datagram.add_be_int32(_file_version);
// Now write the geospecific control points.
datagram.add_be_int32(_geospecific_control_points.size());
if (!_geospecific_control_points.empty()) {
datagram.pad_bytes(4);
GeospecificControlPoints::const_iterator pi;
for (pi = _geospecific_control_points.begin();
pi != _geospecific_control_points.end();
++pi) {
datagram.add_be_float64((*pi)._uv[0]);
datagram.add_be_float64((*pi)._uv[1]);
datagram.add_be_float64((*pi)._real_earth[0]);
datagram.add_be_float64((*pi)._real_earth[1]);
}
}
return FE_ok;
}

View File

@ -0,0 +1,232 @@
// Filename: fltTexture.h
// Created by: drose (25Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTTEXTURE_H
#define FLTTEXTURE_H
#include <pandatoolbase.h>
#include "fltRecord.h"
#include <filename.h>
#include <luse.h>
////////////////////////////////////////////////////////////////////
// Class : FltTexture
// Description : Represents a single texture in the texture palette.
////////////////////////////////////////////////////////////////////
class FltTexture : public FltRecord {
public:
FltTexture(FltHeader *header);
string _filename;
int _pattern_index;
int _x_location;
int _y_location;
Filename get_texture_filename() const;
Filename get_attr_filename() const;
FltError read_attr_data();
FltError write_attr_data() const;
// The remaining fields are from the attr file.
enum FileFormat {
FF_none = -1,
FF_att_8_pattern = 0,
FF_att_8_template = 1,
FF_sgi_i = 2,
FF_sgi_ia = 3,
FF_sgi_rgb = 4,
FF_sgi_rgba = 5
};
enum Minification {
MN_point = 0,
MN_bilinear = 1,
MN_OB_mipmap = 2, // obsolete
MN_mipmap_point = 3,
MN_mipmap_linear = 4,
MN_mipmap_bilinear = 5,
MN_mipmap_trilinear = 6,
MN_bicubic = 8,
MN_bilinear_gequal = 9,
MN_bilinear_lequal = 10,
MN_bicubic_gequal = 11,
MN_bicubic_lequal = 12
};
enum Magnification {
MG_point = 0,
MG_bilinear = 1,
MG_bicubic = 3,
MG_sharpen = 4,
MG_add_detail = 5,
MG_modulate_detail = 6,
MG_bilinear_gequal = 7,
MG_bilinear_lequal = 8,
MG_bicubic_gequal = 9,
MG_bicubic_lequal = 10
};
enum RepeatType {
RT_repeat = 0,
RT_clamp = 1
};
enum EnvironmentType {
ET_modulate = 0,
ET_blend = 1,
ET_decal = 2,
ET_color = 3
};
enum InternalFormat {
IF_default = 0,
IF_i_12a_4 = 1,
IF_ia_8 = 2,
IF_rgb_5 = 3,
IF_rgba_4 = 4,
IF_ia_12 = 5,
IF_rgba_8 = 6,
IF_rgba_12 = 7,
IF_i_16 = 8, // shadow mode only
IF_rgb_12 = 9
};
enum ExternalFormat {
EF_default = 0,
EF_pack_8 = 1,
EF_pack_16 = 2
};
enum ProjectionType {
PT_flat_earth = 0,
PT_lambert = 3,
PT_utm = 4,
PT_undefined = 7
};
enum EarthModel {
EM_wgs84 = 0,
EM_wgs72 = 1,
EM_bessel = 2,
EM_clarke_1866 = 3,
EM_nad27 = 4
};
enum ImageOrigin {
IO_lower_left = 0,
IO_upper_left = 1
};
enum PointsUnits {
PU_degrees = 0,
PU_meters = 1,
PU_pixels = 2
};
enum Hemisphere {
H_southern = 0,
H_northern = 1,
};
struct LODScale {
float _lod;
float _scale;
};
struct GeospecificControlPoint {
LPoint2d _uv;
LPoint2d _real_earth;
};
typedef vector<GeospecificControlPoint> GeospecificControlPoints;
int _num_texels_u;
int _num_texels_v;
int _real_world_size_u;
int _real_world_size_v;
int _up_vector_x;
int _up_vector_y;
FileFormat _file_format;
Minification _min_filter;
Magnification _mag_filter;
RepeatType _repeat;
RepeatType _repeat_u;
RepeatType _repeat_v;
int _modify_flag;
int _x_pivot_point;
int _y_pivot_point;
EnvironmentType _env_type;
bool _intensity_is_alpha; // if true, a one-channel image is actually
// an alpha image, not an intensity image.
double _float_real_world_size_u;
double _float_real_world_size_v;
int _imported_origin_code;
int _kernel_version;
InternalFormat _internal_format;
ExternalFormat _external_format;
bool _use_mipmap_kernel;
float _mipmap_kernel[8];
bool _use_lod_scale;
LODScale _lod_scale[8];
float _clamp;
Magnification _mag_filter_alpha;
Magnification _mag_filter_color;
double _lambert_conic_central_meridian;
double _lambert_conic_upper_latitude;
double _lambert_conic_lower_latitude;
bool _use_detail;
int _detail_j;
int _detail_k;
int _detail_m;
int _detail_n;
int _detail_scramble;
bool _use_tile;
float _tile_lower_left_u;
float _tile_lower_left_v;
float _tile_upper_right_u;
float _tile_upper_right_v;
ProjectionType _projection;
EarthModel _earth_model;
int _utm_zone;
ImageOrigin _image_origin;
PointsUnits _geospecific_points_units;
Hemisphere _geospecific_hemisphere;
string _comment;
int _file_version;
GeospecificControlPoints _geospecific_control_points;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
private:
FltError unpack_attr(const Datagram &datagram);
FltError pack_attr(Datagram &datagram) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltRecord::init_type();
register_type(_type_handle, "FltTexture",
FltRecord::get_class_type());
}
private:
static TypeHandle _type_handle;
friend class FltHeader;
};
#endif

View File

@ -0,0 +1,95 @@
// Filename: fltTrackplane.cxx
// Created by: drose (26Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltTrackplane.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
////////////////////////////////////////////////////////////////////
// Function: FltTrackplane::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltTrackplane::
FltTrackplane() {
_origin.set(0.0, 0.0, 0.0);
_alignment.set(0.0, 0.0, 0.0);
_plane.set(0.0, 0.0, 1.0);
_grid_state = false;
_grid_under = false;
_grid_angle = 0.0;
_grid_spacing_x = 1;
_grid_spacing_y = 1;
_snap_to_grid = false;
_grid_size = 10.0;
_grid_spacing_direction = 0;
_grid_mask = 0;
}
////////////////////////////////////////////////////////////////////
// Function: FltTrackplane::extract_record
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool FltTrackplane::
extract_record(FltRecordReader &reader) {
DatagramIterator &iterator = reader.get_iterator();
_origin[0] = iterator.get_be_float64();
_origin[1] = iterator.get_be_float64();
_origin[2] = iterator.get_be_float64();
_alignment[0] = iterator.get_be_float64();
_alignment[1] = iterator.get_be_float64();
_alignment[0] = iterator.get_be_float64();
_plane[0] = iterator.get_be_float64();
_plane[1] = iterator.get_be_float64();
_plane[2] = iterator.get_be_float64();
_grid_state = (iterator.get_be_int32() != 0);
_grid_under = (iterator.get_be_int32() != 0);
_grid_angle = iterator.get_be_float32();
iterator.skip_bytes(4);
_grid_spacing_x = iterator.get_be_float64();
_grid_spacing_y = iterator.get_be_float64();
_snap_to_grid = (iterator.get_be_int32() != 0);
_grid_size = iterator.get_be_float64();
_grid_spacing_direction = iterator.get_be_int32();
_grid_mask = iterator.get_be_int32();
iterator.skip_bytes(4);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltTrackplane::build_record
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool FltTrackplane::
build_record(FltRecordWriter &writer) const {
Datagram &datagram = writer.update_datagram();
datagram.add_be_float64(_origin[0]);
datagram.add_be_float64(_origin[1]);
datagram.add_be_float64(_origin[2]);
datagram.add_be_float64(_alignment[0]);
datagram.add_be_float64(_alignment[1]);
datagram.add_be_float64(_alignment[2]);
datagram.add_be_float64(_plane[0]);
datagram.add_be_float64(_plane[1]);
datagram.add_be_float64(_plane[2]);
datagram.add_be_int32(_grid_state);
datagram.add_be_int32(_grid_under);
datagram.add_be_float32(_grid_angle);
datagram.pad_bytes(4);
datagram.add_be_float64(_grid_spacing_x);
datagram.add_be_float64(_grid_spacing_y);
datagram.add_be_int32(_snap_to_grid);
datagram.add_be_float64(_grid_size);
datagram.add_be_int32(_grid_spacing_direction);
datagram.add_be_int32(_grid_mask);
datagram.pad_bytes(4);
return true;
}

View File

@ -0,0 +1,46 @@
// Filename: fltTrackplane.h
// Created by: drose (26Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTTRACKPLANE_H
#define FLTTRACKPLANE_H
#include <pandatoolbase.h>
#include <luse.h>
class FltRecordReader;
class FltRecordWriter;
////////////////////////////////////////////////////////////////////
// Class : FltTrackplane
// Description : A single trackplane entry in the eyepoint/trackplane
// palette.
////////////////////////////////////////////////////////////////////
class FltTrackplane {
public:
FltTrackplane();
bool extract_record(FltRecordReader &reader);
bool build_record(FltRecordWriter &writer) const;
public:
LPoint3d _origin;
LPoint3d _alignment;
LVector3d _plane;
bool _grid_state;
bool _grid_under;
float _grid_angle;
double _grid_spacing_x;
double _grid_spacing_y;
bool _snap_to_grid;
double _grid_size;
int _grid_spacing_direction;
int _grid_mask;
};
#endif

View File

@ -0,0 +1,92 @@
// Filename: fltTransformGeneralMatrix.cxx
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltTransformGeneralMatrix.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
TypeHandle FltTransformGeneralMatrix::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltTransformGeneralMatrix::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltTransformGeneralMatrix::
FltTransformGeneralMatrix(FltHeader *header) : FltTransformRecord(header) {
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformGeneralMatrix::set_matrix
// Access: Public
// Description: Directly sets the general matrix.
////////////////////////////////////////////////////////////////////
void FltTransformGeneralMatrix::
set_matrix(const LMatrix4d &matrix) {
_matrix = matrix;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformGeneralMatrix::set_matrix
// Access: Public
// Description: Directly sets the general matrix.
////////////////////////////////////////////////////////////////////
void FltTransformGeneralMatrix::
set_matrix(const LMatrix4f &matrix) {
_matrix = LCAST(double, matrix);
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformGeneralMatrix::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this record based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltTransformGeneralMatrix::
extract_record(FltRecordReader &reader) {
if (!FltTransformRecord::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_general_matrix, false);
DatagramIterator &iterator = reader.get_iterator();
for (int r = 0; r < 4; r++) {
for (int c = 0; c < 4; c++) {
_matrix(r, c) = iterator.get_be_float32();
}
}
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformGeneralMatrix::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltTransformGeneralMatrix::
build_record(FltRecordWriter &writer) const {
if (!FltTransformRecord::build_record(writer)) {
return false;
}
writer.set_opcode(FO_general_matrix);
Datagram &datagram = writer.update_datagram();
for (int r = 0; r < 4; r++) {
for (int c = 0; c < 4; c++) {
datagram.add_be_float32(_matrix(r, c));
}
}
return true;
}

View File

@ -0,0 +1,50 @@
// Filename: fltTransformGeneralMatrix.h
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTTRANSFORMGENERALMATRIX_H
#define FLTTRANSFORMGENERALMATRIX_H
#include <pandatoolbase.h>
#include "fltTransformRecord.h"
////////////////////////////////////////////////////////////////////
// Class : FltTransformGeneralMatrix
// Description : A general 4x4 matrix. This appears in the flt file
// when there is no record of the composition of the
// transform.
////////////////////////////////////////////////////////////////////
class FltTransformGeneralMatrix : public FltTransformRecord {
public:
FltTransformGeneralMatrix(FltHeader *header);
void set_matrix(const LMatrix4d &matrix);
void set_matrix(const LMatrix4f &matrix);
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltTransformRecord::init_type();
register_type(_type_handle, "FltTransformGeneralMatrix",
FltTransformRecord::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#endif

View File

@ -0,0 +1,213 @@
// Filename: fltTransformPut.cxx
// Created by: drose (29Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltTransformPut.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
#include <look_at.h>
TypeHandle FltTransformPut::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltTransformPut::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltTransformPut::
FltTransformPut(FltHeader *header) : FltTransformRecord(header) {
_from_origin.set(0.0, 0.0, 0.0);
_from_align.set(1.0, 0.0, 0.0);
_from_track.set(1.0, 0.0, 0.0);
_to_origin.set(0.0, 0.0, 0.0);
_to_align.set(1.0, 0.0, 0.0);
_to_track.set(1.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformPut::set
// Access: Public
// Description: Defines the put explicitly. The transformation will
// map the three "from" points to the corresponding
// three "to" points.
////////////////////////////////////////////////////////////////////
void FltTransformPut::
set(const LPoint3d &from_origin, const LPoint3d &from_align,
const LPoint3d &from_track,
const LPoint3d &to_origin, const LPoint3d &to_align,
const LPoint3d &to_track) {
_from_origin = from_origin;
_from_align = from_align;
_from_track = from_track;
_to_origin = to_origin;
_to_align = to_align;
_to_track = to_track;
recompute_matrix();
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformPut::get_from_origin
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
const LPoint3d &FltTransformPut::
get_from_origin() const {
return _from_origin;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformPut::get_from_align
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
const LPoint3d &FltTransformPut::
get_from_align() const {
return _from_align;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformPut::get_from_track
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
const LPoint3d &FltTransformPut::
get_from_track() const {
return _from_track;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformPut::get_to_origin
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
const LPoint3d &FltTransformPut::
get_to_origin() const {
return _to_origin;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformPut::get_to_align
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
const LPoint3d &FltTransformPut::
get_to_align() const {
return _to_align;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformPut::get_to_track
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
const LPoint3d &FltTransformPut::
get_to_track() const {
return _to_track;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformPut::recompute_matrix
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void FltTransformPut::
recompute_matrix() {
LMatrix4d r1, r2;
look_at(r1, _from_align - _from_origin, _from_track - _from_origin, CS_zup_right);
look_at(r2, _to_align - _to_origin, _to_track - _to_origin, CS_zup_right);
_matrix =
LMatrix4d::translate_mat(-_from_origin) *
invert(r1) *
r2 *
LMatrix4d::translate_mat(_to_origin);
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformPut::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this record based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltTransformPut::
extract_record(FltRecordReader &reader) {
if (!FltTransformRecord::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_put, false);
DatagramIterator &iterator = reader.get_iterator();
iterator.skip_bytes(4); // Undocumented additional padding.
_from_origin[0] = iterator.get_be_float64();
_from_origin[1] = iterator.get_be_float64();
_from_origin[2] = iterator.get_be_float64();
_from_align[0] = iterator.get_be_float64();
_from_align[1] = iterator.get_be_float64();
_from_align[2] = iterator.get_be_float64();
_from_track[0] = iterator.get_be_float64();
_from_track[1] = iterator.get_be_float64();
_from_track[2] = iterator.get_be_float64();
_to_origin[0] = iterator.get_be_float64();
_to_origin[1] = iterator.get_be_float64();
_to_origin[2] = iterator.get_be_float64();
_to_align[0] = iterator.get_be_float64();
_to_align[1] = iterator.get_be_float64();
_to_align[2] = iterator.get_be_float64();
_to_track[0] = iterator.get_be_float64();
_to_track[1] = iterator.get_be_float64();
_to_track[2] = iterator.get_be_float64();
recompute_matrix();
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformPut::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltTransformPut::
build_record(FltRecordWriter &writer) const {
if (!FltTransformRecord::build_record(writer)) {
return false;
}
writer.set_opcode(FO_put);
Datagram &datagram = writer.update_datagram();
datagram.pad_bytes(4); // Undocumented additional padding.
datagram.add_be_float64(_from_origin[0]);
datagram.add_be_float64(_from_origin[1]);
datagram.add_be_float64(_from_origin[2]);
datagram.add_be_float64(_from_align[0]);
datagram.add_be_float64(_from_align[1]);
datagram.add_be_float64(_from_align[2]);
datagram.add_be_float64(_from_track[0]);
datagram.add_be_float64(_from_track[1]);
datagram.add_be_float64(_from_track[2]);
datagram.add_be_float64(_to_origin[0]);
datagram.add_be_float64(_to_origin[1]);
datagram.add_be_float64(_to_origin[2]);
datagram.add_be_float64(_to_align[0]);
datagram.add_be_float64(_to_align[1]);
datagram.add_be_float64(_to_align[2]);
datagram.add_be_float64(_to_track[0]);
datagram.add_be_float64(_to_track[1]);
datagram.add_be_float64(_to_track[2]);
return true;
}

View File

@ -0,0 +1,71 @@
// Filename: fltTransformPut.h
// Created by: drose (29Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTTRANSFORMPUT_H
#define FLTTRANSFORMPUT_H
#include <pandatoolbase.h>
#include "fltTransformRecord.h"
////////////////////////////////////////////////////////////////////
// Class : FltTransformPut
// Description : A "put", which is a MultiGen concept of defining a
// transformation by mapping three arbitrary points to
// three new arbitrary points.
////////////////////////////////////////////////////////////////////
class FltTransformPut : public FltTransformRecord {
public:
FltTransformPut(FltHeader *header);
void set(const LPoint3d &from_origin,
const LPoint3d &from_align,
const LPoint3d &from_track,
const LPoint3d &to_origin,
const LPoint3d &to_align,
const LPoint3d &to_track);
const LPoint3d &get_from_origin() const;
const LPoint3d &get_from_align() const;
const LPoint3d &get_from_track() const;
const LPoint3d &get_to_origin() const;
const LPoint3d &get_to_align() const;
const LPoint3d &get_to_track() const;
private:
void recompute_matrix();
LPoint3d _from_origin;
LPoint3d _from_align;
LPoint3d _from_track;
LPoint3d _to_origin;
LPoint3d _to_align;
LPoint3d _to_track;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltTransformRecord::init_type();
register_type(_type_handle, "FltTransformPut",
FltTransformRecord::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#endif

View File

@ -0,0 +1,29 @@
// Filename: fltTransformRecord.cxx
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltTransformRecord.h"
TypeHandle FltTransformRecord::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltTransformRecord::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltTransformRecord::
FltTransformRecord(FltHeader *header) : FltRecord(header) {
_matrix = LMatrix4d::ident_mat();
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRecord::get_matrix
// Access: Public
// Description: Returns the transform matrix represented by this
// particular component of the transform.
////////////////////////////////////////////////////////////////////
const LMatrix4d &FltTransformRecord::
get_matrix() const {
return _matrix;
}

View File

@ -0,0 +1,53 @@
// Filename: fltTransformRecord.h
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTTRANSFORMRECORD_H
#define FLTTRANSFORMRECORD_H
#include <pandatoolbase.h>
#include "fltRecord.h"
#include <luse.h>
////////////////////////////////////////////////////////////////////
// Class : FltTransformRecord
// Description : A base class for a number of types of ancillary
// records that follow beads and indicate some kind of a
// transformation. Pointers of this type are collected
// in the FltTransformation class.
////////////////////////////////////////////////////////////////////
class FltTransformRecord : public FltRecord {
public:
FltTransformRecord(FltHeader *header);
const LMatrix4d &get_matrix() const;
protected:
LMatrix4d _matrix;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltRecord::init_type();
register_type(_type_handle, "FltTransformRecord",
FltRecord::get_class_type());
}
private:
static TypeHandle _type_handle;
friend class FltBead;
};
#endif

View File

@ -0,0 +1,155 @@
// Filename: fltTransformRotateAboutEdge.cxx
// Created by: drose (30Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltTransformRotateAboutEdge.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
TypeHandle FltTransformRotateAboutEdge::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateAboutEdge::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltTransformRotateAboutEdge::
FltTransformRotateAboutEdge(FltHeader *header) : FltTransformRecord(header) {
_point_a.set(0.0, 0.0, 0.0);
_point_b.set(1.0, 0.0, 0.0);
_angle = 0.0;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateAboutEdge::set
// Access: Public
// Description: Defines the rotation. The angle is given in degrees,
// counterclockwise about the axis as seen from point a.
////////////////////////////////////////////////////////////////////
void FltTransformRotateAboutEdge::
set(const LPoint3d &point_a, const LPoint3d &point_b, float angle) {
_point_a = point_a;
_point_b = point_b;
_angle = angle;
recompute_matrix();
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateAboutEdge::get_point_a
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
const LPoint3d &FltTransformRotateAboutEdge::
get_point_a() const {
return _point_a;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateAboutEdge::get_point_b
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
const LPoint3d &FltTransformRotateAboutEdge::
get_point_b() const {
return _point_b;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateAboutEdge::get_angle
// Access: Public
// Description: Returns the angle of rotation, in degrees
// counterclockwise about the axis as seen from point a.
////////////////////////////////////////////////////////////////////
float FltTransformRotateAboutEdge::
get_angle() const {
return _angle;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateAboutEdge::recompute_matrix
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void FltTransformRotateAboutEdge::
recompute_matrix() {
if (_point_a == _point_b) {
// Degenerate case.
_matrix = LMatrix4d::ident_mat();
} else {
LVector3d axis = _point_b - _point_a;
_matrix =
LMatrix4d::translate_mat(-_point_a) *
LMatrix4d::rotate_mat(_angle, normalize(axis), CS_zup_right) *
LMatrix4d::translate_mat(_point_a);
}
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateAboutEdge::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this record based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltTransformRotateAboutEdge::
extract_record(FltRecordReader &reader) {
if (!FltTransformRecord::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_rotate_about_edge, false);
DatagramIterator &iterator = reader.get_iterator();
iterator.skip_bytes(4); // Undocumented additional padding.
_point_a[0] = iterator.get_be_float64();
_point_a[1] = iterator.get_be_float64();
_point_a[2] = iterator.get_be_float64();
_point_b[0] = iterator.get_be_float64();
_point_b[1] = iterator.get_be_float64();
_point_b[2] = iterator.get_be_float64();
_angle = iterator.get_be_float32();
iterator.skip_bytes(4); // Undocumented additional padding.
recompute_matrix();
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateAboutEdge::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltTransformRotateAboutEdge::
build_record(FltRecordWriter &writer) const {
if (!FltTransformRecord::build_record(writer)) {
return false;
}
writer.set_opcode(FO_rotate_about_edge);
Datagram &datagram = writer.update_datagram();
datagram.pad_bytes(4); // Undocumented additional padding.
datagram.add_be_float64(_point_a[0]);
datagram.add_be_float64(_point_a[1]);
datagram.add_be_float64(_point_a[2]);
datagram.add_be_float64(_point_b[0]);
datagram.add_be_float64(_point_b[1]);
datagram.add_be_float64(_point_b[2]);
datagram.add_be_float32(_angle);
datagram.pad_bytes(4); // Undocumented additional padding.
return true;
}

View File

@ -0,0 +1,57 @@
// Filename: fltTransformRotateAboutEdge.h
// Created by: drose (30Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTTRANSFORMROTATEABOUTEDGE_H
#define FLTTRANSFORMROTATEABOUTEDGE_H
#include <pandatoolbase.h>
#include "fltTransformRecord.h"
////////////////////////////////////////////////////////////////////
// Class : FltTransformRotateAboutEdge
// Description : A transformation that rotates about a particular axis
// in space, defined by two endpoints.
////////////////////////////////////////////////////////////////////
class FltTransformRotateAboutEdge : public FltTransformRecord {
public:
FltTransformRotateAboutEdge(FltHeader *header);
void set(const LPoint3d &point_a, const LPoint3d &point_b, float angle);
const LPoint3d &get_point_a() const;
const LPoint3d &get_point_b() const;
float get_angle() const;
private:
void recompute_matrix();
LPoint3d _point_a;
LPoint3d _point_b;
float _angle;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltTransformRecord::init_type();
register_type(_type_handle, "FltTransformRotateAboutEdge",
FltTransformRecord::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#endif

View File

@ -0,0 +1,152 @@
// Filename: fltTransformRotateAboutPoint.cxx
// Created by: drose (30Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltTransformRotateAboutPoint.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
TypeHandle FltTransformRotateAboutPoint::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateAboutPoint::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltTransformRotateAboutPoint::
FltTransformRotateAboutPoint(FltHeader *header) : FltTransformRecord(header) {
_center.set(0.0, 0.0, 0.0);
_axis.set(1.0, 0.0, 0.0);
_angle = 0.0;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateAboutPoint::set
// Access: Public
// Description: Defines the rotation. The angle is given in degrees,
// counterclockwise about the axis as seen from point a.
////////////////////////////////////////////////////////////////////
void FltTransformRotateAboutPoint::
set(const LPoint3d &center, const LVector3f &axis, float angle) {
_center = center;
_axis = axis;
_angle = angle;
recompute_matrix();
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateAboutPoint::get_center
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
const LPoint3d &FltTransformRotateAboutPoint::
get_center() const {
return _center;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateAboutPoint::get_axis
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
const LVector3f &FltTransformRotateAboutPoint::
get_axis() const {
return _axis;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateAboutPoint::get_angle
// Access: Public
// Description: Returns the angle of rotation, in degrees
// counterclockwise about the axis.
////////////////////////////////////////////////////////////////////
float FltTransformRotateAboutPoint::
get_angle() const {
return _angle;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateAboutPoint::recompute_matrix
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void FltTransformRotateAboutPoint::
recompute_matrix() {
if (_axis == LVector3f::zero()) {
// Degenerate case.
_matrix = LMatrix4d::ident_mat();
} else {
LVector3d axis = LCAST(double, axis);
_matrix =
LMatrix4d::translate_mat(-_center) *
LMatrix4d::rotate_mat(_angle, normalize(axis), CS_zup_right) *
LMatrix4d::translate_mat(_center);
}
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateAboutPoint::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this record based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltTransformRotateAboutPoint::
extract_record(FltRecordReader &reader) {
if (!FltTransformRecord::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_rotate_about_point, false);
DatagramIterator &iterator = reader.get_iterator();
iterator.skip_bytes(4); // Undocumented additional padding.
_center[0] = iterator.get_be_float64();
_center[1] = iterator.get_be_float64();
_center[2] = iterator.get_be_float64();
_axis[0] = iterator.get_be_float32();
_axis[1] = iterator.get_be_float32();
_axis[2] = iterator.get_be_float32();
_angle = iterator.get_be_float32();
recompute_matrix();
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateAboutPoint::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltTransformRotateAboutPoint::
build_record(FltRecordWriter &writer) const {
if (!FltTransformRecord::build_record(writer)) {
return false;
}
writer.set_opcode(FO_rotate_about_point);
Datagram &datagram = writer.update_datagram();
datagram.pad_bytes(4); // Undocumented additional padding.
datagram.add_be_float64(_center[0]);
datagram.add_be_float64(_center[1]);
datagram.add_be_float64(_center[2]);
datagram.add_be_float32(_axis[0]);
datagram.add_be_float32(_axis[1]);
datagram.add_be_float32(_axis[2]);
datagram.add_be_float32(_angle);
return true;
}

View File

@ -0,0 +1,57 @@
// Filename: fltTransformRotateAboutPoint.h
// Created by: drose (30Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTTRANSFORMROTATEABOUTPOINT_H
#define FLTTRANSFORMROTATEABOUTPOINT_H
#include <pandatoolbase.h>
#include "fltTransformRecord.h"
////////////////////////////////////////////////////////////////////
// Class : FltTransformRotateAboutPoint
// Description : A transformation that rotates about a particular axis
// in space, defined by a point and vector.
////////////////////////////////////////////////////////////////////
class FltTransformRotateAboutPoint : public FltTransformRecord {
public:
FltTransformRotateAboutPoint(FltHeader *header);
void set(const LPoint3d &center, const LVector3f &axis, float angle);
const LPoint3d &get_center() const;
const LVector3f &get_axis() const;
float get_angle() const;
private:
void recompute_matrix();
LPoint3d _center;
LVector3f _axis;
float _angle;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltTransformRecord::init_type();
register_type(_type_handle, "FltTransformRotateAboutPoint",
FltTransformRecord::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#endif

View File

@ -0,0 +1,230 @@
// Filename: fltTransformRotateScale.cxx
// Created by: drose (30Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltTransformRotateScale.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
#include <mathNumbers.h>
#include <look_at.h>
TypeHandle FltTransformRotateScale::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateScale::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltTransformRotateScale::
FltTransformRotateScale(FltHeader *header) : FltTransformRecord(header) {
_center.set(0.0, 0.0, 0.0);
_reference_point.set(0.0, 0.0, 0.0);
_to_point.set(0.0, 0.0, 0.0);
_overall_scale = 1.0;
_axis_scale = 1.0;
_angle = 0.0;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateScale::set
// Access: Public
// Description: Defines the transform explicitly. The angle of
// rotation is determined by the angle between the
// reference point and the to point (relative to the
// center), and the scale factor is determined by the
// distance between the reference point and the center
// point. If axis_scale is true, the scale is along
// reference point axis only; otherwise, it is a uniform
// scale.
////////////////////////////////////////////////////////////////////
void FltTransformRotateScale::
set(const LPoint3d &center, const LPoint3d &reference_point,
const LPoint3d &to_point, bool axis_scale) {
_center = center;
_reference_point = reference_point;
_to_point = to_point;
LVector3d v1 = _reference_point - _center;
LVector3d v2 = _to_point - _center;
_angle =
acos(dot(normalize(v1), normalize(v2))) * 180.0 / MathNumbers::pi;
if (axis_scale) {
_axis_scale = length(v1);
_overall_scale = 1.0;
} else {
_overall_scale = length(v1);
_axis_scale = 1.0;
}
recompute_matrix();
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateScale::get_center
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
const LPoint3d &FltTransformRotateScale::
get_center() const {
return _center;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateScale::get_reference_point
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
const LPoint3d &FltTransformRotateScale::
get_reference_point() const {
return _reference_point;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateScale::get_to_point
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
const LPoint3d &FltTransformRotateScale::
get_to_point() const {
return _to_point;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateScale::get_overall_scale
// Access: Public
// Description: Returns the overall scale factor.
////////////////////////////////////////////////////////////////////
float FltTransformRotateScale::
get_overall_scale() const {
return _overall_scale;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateScale::get_axis_scale
// Access: Public
// Description: Returns the scale factor in the direction of the
// axis.
////////////////////////////////////////////////////////////////////
float FltTransformRotateScale::
get_axis_scale() const {
return _axis_scale;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateScale::get_angle
// Access: Public
// Description: Returns the angle of rotation in degrees.
////////////////////////////////////////////////////////////////////
float FltTransformRotateScale::
get_angle() const {
return _angle;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateScale::recompute_matrix
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void FltTransformRotateScale::
recompute_matrix() {
LVector3d v1 = _reference_point - _center;
LVector3d v2 = _to_point - _center;
LVector3d rotate_axis = normalize(cross(v1, v2));
// To scale along an axis, we have to do a bit of work. First
// determine the matrices to rotate and unrotate the rotate axis
// to the y-forward axis.
LMatrix4d r1;
look_at(r1, v1, rotate_axis, CS_zup_right);
_matrix =
LMatrix4d::translate_mat(-_center) *
r1 *
LMatrix4d::scale_mat(1.0, _axis_scale, 1.0) *
LMatrix4d::scale_mat(_overall_scale) *
invert(r1) *
LMatrix4d::rotate_mat(_angle, rotate_axis, CS_zup_right) *
LMatrix4d::translate_mat(_center);
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateScale::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this record based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltTransformRotateScale::
extract_record(FltRecordReader &reader) {
if (!FltTransformRecord::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_rotate_and_scale, false);
DatagramIterator &iterator = reader.get_iterator();
iterator.skip_bytes(4); // Undocumented additional padding.
_center[0] = iterator.get_be_float64();
_center[1] = iterator.get_be_float64();
_center[2] = iterator.get_be_float64();
_reference_point[0] = iterator.get_be_float64();
_reference_point[1] = iterator.get_be_float64();
_reference_point[2] = iterator.get_be_float64();
_to_point[0] = iterator.get_be_float64();
_to_point[1] = iterator.get_be_float64();
_to_point[2] = iterator.get_be_float64();
_overall_scale = iterator.get_be_float32();
_axis_scale = iterator.get_be_float32();
_angle = iterator.get_be_float32();
iterator.skip_bytes(4); // Undocumented additional padding.
recompute_matrix();
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformRotateScale::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltTransformRotateScale::
build_record(FltRecordWriter &writer) const {
if (!FltTransformRecord::build_record(writer)) {
return false;
}
writer.set_opcode(FO_put);
Datagram &datagram = writer.update_datagram();
datagram.pad_bytes(4); // Undocumented additional padding.
datagram.add_be_float64(_center[0]);
datagram.add_be_float64(_center[1]);
datagram.add_be_float64(_center[2]);
datagram.add_be_float64(_reference_point[0]);
datagram.add_be_float64(_reference_point[1]);
datagram.add_be_float64(_reference_point[2]);
datagram.add_be_float64(_to_point[0]);
datagram.add_be_float64(_to_point[1]);
datagram.add_be_float64(_to_point[2]);
datagram.add_be_float32(_overall_scale);
datagram.add_be_float32(_axis_scale);
datagram.add_be_float32(_angle);
datagram.pad_bytes(4); // Undocumented additional padding.
return true;
}

View File

@ -0,0 +1,66 @@
// Filename: fltTransformRotateScale.h
// Created by: drose (30Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTTRANSFORMROTATESCALE_H
#define FLTTRANSFORMROTATESCALE_H
#include <pandatoolbase.h>
#include "fltTransformRecord.h"
////////////////////////////////////////////////////////////////////
// Class : FltTransformRotateScale
// Description : A combination rotation and scale. This is sometimes
// called "Rotate To Point" within MultiGen.
////////////////////////////////////////////////////////////////////
class FltTransformRotateScale : public FltTransformRecord {
public:
FltTransformRotateScale(FltHeader *header);
void set(const LPoint3d &center, const LPoint3d &reference_point,
const LPoint3d &to_point, bool axis_scale);
const LPoint3d &get_center() const;
const LPoint3d &get_reference_point() const;
const LPoint3d &get_to_point() const;
float get_overall_scale() const;
float get_axis_scale() const;
float get_angle() const;
private:
void recompute_matrix();
LPoint3d _center;
LPoint3d _reference_point;
LPoint3d _to_point;
float _overall_scale;
float _axis_scale;
float _angle;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltTransformRecord::init_type();
register_type(_type_handle, "FltTransformRotateScale",
FltTransformRecord::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#endif

View File

@ -0,0 +1,133 @@
// Filename: fltTransformScale.cxx
// Created by: drose (30Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltTransformScale.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
TypeHandle FltTransformScale::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltTransformScale::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltTransformScale::
FltTransformScale(FltHeader *header) : FltTransformRecord(header) {
_center.set(0.0, 0.0, 0.0);
_scale.set(1.0, 1.0, 1.0);
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformScale::set
// Access: Public
// Description: Defines the scale.
////////////////////////////////////////////////////////////////////
void FltTransformScale::
set(const LPoint3d &center, const LVecBase3f &scale) {
_center = center;
_scale = scale;
recompute_matrix();
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformScale::get_center
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
const LPoint3d &FltTransformScale::
get_center() const {
return _center;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformScale::get_scale
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
const LVecBase3f &FltTransformScale::
get_scale() const {
return _scale;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformScale::recompute_matrix
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void FltTransformScale::
recompute_matrix() {
_matrix =
LMatrix4d::translate_mat(-_center) *
LMatrix4d::scale_mat(LCAST(double, _scale)) *
LMatrix4d::translate_mat(_center);
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformScale::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this record based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltTransformScale::
extract_record(FltRecordReader &reader) {
if (!FltTransformRecord::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_scale, false);
DatagramIterator &iterator = reader.get_iterator();
iterator.skip_bytes(4); // Undocumented additional padding.
_center[0] = iterator.get_be_float64();
_center[1] = iterator.get_be_float64();
_center[2] = iterator.get_be_float64();
_scale[0] = iterator.get_be_float32();
_scale[1] = iterator.get_be_float32();
_scale[2] = iterator.get_be_float32();
iterator.skip_bytes(4); // Undocumented additional padding.
recompute_matrix();
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformScale::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltTransformScale::
build_record(FltRecordWriter &writer) const {
if (!FltTransformRecord::build_record(writer)) {
return false;
}
writer.set_opcode(FO_scale);
Datagram &datagram = writer.update_datagram();
datagram.pad_bytes(4); // Undocumented additional padding.
datagram.add_be_float64(_center[0]);
datagram.add_be_float64(_center[1]);
datagram.add_be_float64(_center[2]);
datagram.add_be_float32(_scale[0]);
datagram.add_be_float32(_scale[1]);
datagram.add_be_float32(_scale[2]);
datagram.pad_bytes(4); // Undocumented additional padding.
return true;
}

View File

@ -0,0 +1,55 @@
// Filename: fltTransformScale.h
// Created by: drose (30Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTTRANSFORMSCALE_H
#define FLTTRANSFORMSCALE_H
#include <pandatoolbase.h>
#include "fltTransformRecord.h"
////////////////////////////////////////////////////////////////////
// Class : FltTransformScale
// Description : A transformation that applies a (possibly nonuniform)
// scale.
////////////////////////////////////////////////////////////////////
class FltTransformScale : public FltTransformRecord {
public:
FltTransformScale(FltHeader *header);
void set(const LPoint3d &center, const LVecBase3f &scale);
const LPoint3d &get_center() const;
const LVecBase3f &get_scale() const;
private:
void recompute_matrix();
LPoint3d _center;
LVecBase3f _scale;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltTransformRecord::init_type();
register_type(_type_handle, "FltTransformScale",
FltTransformRecord::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#endif

View File

@ -0,0 +1,132 @@
// Filename: fltTransformTranslate.cxx
// Created by: drose (30Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltTransformTranslate.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
TypeHandle FltTransformTranslate::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltTransformTranslate::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltTransformTranslate::
FltTransformTranslate(FltHeader *header) : FltTransformRecord(header) {
_from.set(0.0, 0.0, 0.0);
_delta.set(0.0, 0.0, 0.0);
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformTranslate::set
// Access: Public
// Description: Defines the translation. The "from" point seems to
// be pretty much ignored.
////////////////////////////////////////////////////////////////////
void FltTransformTranslate::
set(const LPoint3d &from, const LVector3d &delta) {
_from = from;
_delta = delta;
recompute_matrix();
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformTranslate::get_from
// Access: Public
// Description: Returns the reference point of the translation. This
// is largely meaningless.
////////////////////////////////////////////////////////////////////
const LPoint3d &FltTransformTranslate::
get_from() const {
return _from;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformTranslate::get_delta
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
const LVector3d &FltTransformTranslate::
get_delta() const {
return _delta;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformTranslate::recompute_matrix
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void FltTransformTranslate::
recompute_matrix() {
_matrix = LMatrix4d::translate_mat(_delta);
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformTranslate::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this record based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltTransformTranslate::
extract_record(FltRecordReader &reader) {
if (!FltTransformRecord::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_translate, false);
DatagramIterator &iterator = reader.get_iterator();
iterator.skip_bytes(4); // Undocumented additional padding.
_from[0] = iterator.get_be_float64();
_from[1] = iterator.get_be_float64();
_from[2] = iterator.get_be_float64();
_delta[0] = iterator.get_be_float64();
_delta[1] = iterator.get_be_float64();
_delta[2] = iterator.get_be_float64();
// iterator.skip_bytes(4); // Undocumented additional padding.
recompute_matrix();
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltTransformTranslate::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltTransformTranslate::
build_record(FltRecordWriter &writer) const {
if (!FltTransformRecord::build_record(writer)) {
return false;
}
writer.set_opcode(FO_translate);
Datagram &datagram = writer.update_datagram();
datagram.pad_bytes(4); // Undocumented additional padding.
datagram.add_be_float64(_from[0]);
datagram.add_be_float64(_from[1]);
datagram.add_be_float64(_from[2]);
datagram.add_be_float64(_delta[0]);
datagram.add_be_float64(_delta[1]);
datagram.add_be_float64(_delta[2]);
// datagram.pad_bytes(4); // Undocumented additional padding.
return true;
}

View File

@ -0,0 +1,55 @@
// Filename: fltTransformTranslate.h
// Created by: drose (30Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTTRANSFORMTRANSLATE_H
#define FLTTRANSFORMTRANSLATE_H
#include <pandatoolbase.h>
#include "fltTransformRecord.h"
////////////////////////////////////////////////////////////////////
// Class : FltTransformTranslate
// Description : A transformation that applies a (possibly nonuniform)
// scale.
////////////////////////////////////////////////////////////////////
class FltTransformTranslate : public FltTransformRecord {
public:
FltTransformTranslate(FltHeader *header);
void set(const LPoint3d &from, const LVector3d &delta);
const LPoint3d &get_from() const;
const LVector3d &get_delta() const;
private:
void recompute_matrix();
LPoint3d _from;
LVector3d _delta;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltTransformRecord::init_type();
register_type(_type_handle, "FltTransformTranslate",
FltTransformRecord::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#endif

View File

@ -0,0 +1,63 @@
// Filename: fltUnsupportedRecord.cxx
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltUnsupportedRecord.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
TypeHandle FltUnsupportedRecord::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltUnsupportedRecord::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltUnsupportedRecord::
FltUnsupportedRecord(FltHeader *header) : FltRecord(header) {
_opcode = FO_none;
}
////////////////////////////////////////////////////////////////////
// Function: FltUnsupportedRecord::output
// Access: Public
// Description: Writes a quick one-line description of the bead, but
// not its children. This is a human-readable
// description, primarily for debugging; to write a flt
// file, use FltHeader::write_flt().
////////////////////////////////////////////////////////////////////
void FltUnsupportedRecord::
output(ostream &out) const {
out << "Unsupported(" << _opcode << ")";
}
////////////////////////////////////////////////////////////////////
// Function: FltUnsupportedRecord::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this bead based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltUnsupportedRecord::
extract_record(FltRecordReader &reader) {
_opcode = reader.get_opcode();
_datagram = reader.get_datagram();
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltUnsupportedRecord::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltUnsupportedRecord::
build_record(FltRecordWriter &writer) const {
writer.set_opcode(_opcode);
writer.set_datagram(_datagram);
}

View File

@ -0,0 +1,53 @@
// Filename: fltUnsupportedRecord.h
// Created by: drose (24Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTUNSUPPORTEDRECORD_H
#define FLTUNSUPPORTEDRECORD_H
#include <pandatoolbase.h>
#include "fltRecord.h"
#include <datagram.h>
////////////////////////////////////////////////////////////////////
// Class : FltUnsupportedRecord
// Description :
////////////////////////////////////////////////////////////////////
class FltUnsupportedRecord : public FltRecord {
public:
FltUnsupportedRecord(FltHeader *header);
virtual void output(ostream &out) const;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
private:
FltOpcode _opcode;
Datagram _datagram;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltRecord::init_type();
register_type(_type_handle, "FltUnsupportedRecord",
FltRecord::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#endif

View File

@ -0,0 +1,16 @@
// Filename: fltVertex.I
// Created by: drose (30Aug00)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: FltVertex::has_color
// Access: Public
// Description: Returns true if the vertex has a primary color
// indicated, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool FltVertex::
has_color() const {
return (_flags & F_no_color) == 0;
}

View File

@ -0,0 +1,221 @@
// Filename: fltVertex.cxx
// Created by: drose (25Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltVertex.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
#include "fltHeader.h"
TypeHandle FltVertex::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltVertex::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltVertex::
FltVertex(FltHeader *header) : FltRecord(header) {
_color_name_index = 0;
_flags = 0;
_pos.set(0.0, 0.0, 0.0);
_normal.set(0.0, 0.0, 0.0);
_uv.set(0.0, 0.0);
_color_index = 0;
_has_normal = false;
_has_uv = false;
}
////////////////////////////////////////////////////////////////////
// Function: FltVertex::get_opcode
// Access: Public
// Description: Returns the opcode that this record will be written
// as.
////////////////////////////////////////////////////////////////////
FltOpcode FltVertex::
get_opcode() const {
if (_has_normal) {
if (_has_uv) {
return FO_vertex_cnu;
} else {
return FO_vertex_cn;
}
} else {
if (_has_uv) {
return FO_vertex_cu;
} else {
return FO_vertex_c;
}
}
}
////////////////////////////////////////////////////////////////////
// Function: FltVertex::get_record_length
// Access: Public
// Description: Returns the length of this record in bytes as it will
// be written to the flt file.
////////////////////////////////////////////////////////////////////
int FltVertex::
get_record_length() const {
switch (get_opcode()) {
case FO_vertex_c:
return 40;
case FO_vertex_cn:
return 52;
case FO_vertex_cnu:
return 60;
case FO_vertex_cu:
return 48;
default:
nassertr(false, 0);
}
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: FltVertex::get_color
// Access: Public
// Description: If has_color() indicates true, returns the primary
// color of the face, as a four-component value. In the
// case of a vertex, the alpha channel will always be
// 1.0, as MultiGen does not store transparency
// per-vertex.
////////////////////////////////////////////////////////////////////
Colorf FltVertex::
get_color() const {
nassertr(has_color(), Colorf(0.0, 0.0, 0.0, 0.0));
return _header->get_color(_color_index, (_flags & F_packed_color) != 0,
_packed_color, 0);
}
////////////////////////////////////////////////////////////////////
// Function: FltVertex::get_rgb
// Access: Public
// Description: If has_color() indicates true, returns the primary
// color of the face, as a three-component value
// ignoring transparency.
////////////////////////////////////////////////////////////////////
RGBColorf FltVertex::
get_rgb() const {
nassertr(has_color(), RGBColorf(0.0, 0.0, 0.0));
return _header->get_rgb(_color_index, (_flags & F_packed_color) != 0,
_packed_color);
}
////////////////////////////////////////////////////////////////////
// Function: FltVertex::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this record based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltVertex::
extract_record(FltRecordReader &reader) {
if (!FltRecord::extract_record(reader)) {
return false;
}
switch (reader.get_opcode()) {
case FO_vertex_c:
_has_normal = false;
_has_uv = false;
break;
case FO_vertex_cn:
_has_normal = true;
_has_uv = false;
break;
case FO_vertex_cnu:
_has_normal = true;
_has_uv = true;
break;
case FO_vertex_cu:
_has_normal = false;
_has_uv = true;
break;
default:
nassertr(false, false);
}
DatagramIterator &iterator = reader.get_iterator();
_color_name_index = iterator.get_be_int16();
_flags = iterator.get_be_uint16();
_pos[0] = iterator.get_be_float64();
_pos[1] = iterator.get_be_float64();
_pos[2] = iterator.get_be_float64();
if (_has_normal) {
_normal[0] = iterator.get_be_float32();
_normal[1] = iterator.get_be_float32();
_normal[2] = iterator.get_be_float32();
}
if (_has_uv) {
_uv[0] = iterator.get_be_float32();
_uv[1] = iterator.get_be_float32();
}
if (!_packed_color.extract_record(reader)) {
return false;
}
_color_index = iterator.get_be_uint32();
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltVertex::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltVertex::
build_record(FltRecordWriter &writer) const {
if (!FltRecord::build_record(writer)) {
return false;
}
writer.set_opcode(get_opcode());
Datagram &datagram = writer.update_datagram();
datagram.add_be_int16(_color_name_index);
datagram.add_be_uint16(_flags);
datagram.add_be_float64(_pos[0]);
datagram.add_be_float64(_pos[1]);
datagram.add_be_float64(_pos[2]);
if (_has_normal) {
datagram.add_be_float32(_normal[0]);
datagram.add_be_float32(_normal[1]);
datagram.add_be_float32(_normal[2]);
}
if (_has_uv) {
datagram.add_be_float32(_uv[0]);
datagram.add_be_float32(_uv[1]);
}
if (!_packed_color.build_record(writer)) {
return false;
}
datagram.add_be_uint32(_color_index);
nassertr(datagram.get_length() == get_record_length() - 4, true);
return true;
}

View File

@ -0,0 +1,85 @@
// Filename: fltVertex.h
// Created by: drose (25Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTVERTEX_H
#define FLTVERTEX_H
#include <pandatoolbase.h>
#include "fltRecord.h"
#include "fltPackedColor.h"
#include <luse.h>
////////////////////////////////////////////////////////////////////
// Class : FltVertex
// Description : Represents a single vertex in the vertex palette.
// Flt files index vertices by their byte offset in the
// vertex palette; within this library, we map those
// byte offsets to pointers automatically.
//
// This may represent a vertex with or without a normal
// or texture coordinates.
////////////////////////////////////////////////////////////////////
class FltVertex : public FltRecord {
public:
FltVertex(FltHeader *header);
FltOpcode get_opcode() const;
int get_record_length() const;
enum Flags {
F_hard_edge = 0x80000000,
F_normal_frozen = 0x40000000,
F_no_color = 0x20000000,
F_packed_color = 0x10000000
};
int _color_name_index;
unsigned int _flags;
LPoint3d _pos;
LPoint3f _normal;
LPoint2f _uv;
FltPackedColor _packed_color;
int _color_index;
bool _has_normal;
bool _has_uv;
public:
INLINE bool has_color() const;
Colorf get_color() const;
RGBColorf get_rgb() const;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltRecord::init_type();
register_type(_type_handle, "FltVertex",
FltRecord::get_class_type());
}
private:
static TypeHandle _type_handle;
friend class FltHeader;
};
#include "fltVertex.I"
#endif

View File

@ -0,0 +1,128 @@
// Filename: fltVertexList.cxx
// Created by: drose (25Aug00)
//
////////////////////////////////////////////////////////////////////
#include "fltVertexList.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
#include "fltHeader.h"
TypeHandle FltVertexList::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltVertexList::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltVertexList::
FltVertexList(FltHeader *header) : FltRecord(header) {
}
////////////////////////////////////////////////////////////////////
// Function: FltVertexList::get_num_vertices
// Access: Public
// Description: Returns the number of vertices in this vertex list.
////////////////////////////////////////////////////////////////////
int FltVertexList::
get_num_vertices() const {
return _vertices.size();
}
////////////////////////////////////////////////////////////////////
// Function: FltVertexList::get_vertex
// Access: Public
// Description: Returns the nth vertex of this vertex list.
////////////////////////////////////////////////////////////////////
FltVertex *FltVertexList::
get_vertex(int n) const {
nassertr(n >= 0 && n < (int)_vertices.size(), 0);
return _vertices[n];
}
////////////////////////////////////////////////////////////////////
// Function: FltVertexList::clear_vertices
// Access: Public
// Description: Removes all vertices from this vertex list.
////////////////////////////////////////////////////////////////////
void FltVertexList::
clear_vertices() {
_vertices.clear();
}
////////////////////////////////////////////////////////////////////
// Function: FltVertexList::add_vertex
// Access: Public
// Description: Adds a new vertex to the end of the vertex list.
// Care must be taken to ensure the vertex is also added
// to the vertex palette.
////////////////////////////////////////////////////////////////////
void FltVertexList::
add_vertex(FltVertex *vertex) {
_vertices.push_back(vertex);
}
////////////////////////////////////////////////////////////////////
// Function: FltVertexList::output
// Access: Public
// Description: Writes a quick one-line description of the record, but
// not its children. This is a human-readable
// description, primarily for debugging; to write a flt
// file, use FltHeader::write_flt().
////////////////////////////////////////////////////////////////////
void FltVertexList::
output(ostream &out) const {
out << _vertices.size() << " vertices";
}
////////////////////////////////////////////////////////////////////
// Function: FltVertexList::extract_record
// Access: Protected, Virtual
// Description: Fills in the information in this bead based on the
// information given in the indicated datagram, whose
// opcode has already been read. Returns true on
// success, false if the datagram is invalid.
////////////////////////////////////////////////////////////////////
bool FltVertexList::
extract_record(FltRecordReader &reader) {
if (!FltRecord::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_vertex_list, false);
DatagramIterator &iterator = reader.get_iterator();
_vertices.clear();
while (iterator.get_remaining_size() >= 4) {
int vertex_offset = iterator.get_be_int32();
_vertices.push_back(_header->get_vertex_by_offset(vertex_offset));
}
nassertr(iterator.get_remaining_size() == 0, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltVertexList::build_record
// Access: Protected, Virtual
// Description: Fills up the current record on the FltRecordWriter with
// data for this record, but does not advance the
// writer. Returns true on success, false if there is
// some error.
////////////////////////////////////////////////////////////////////
bool FltVertexList::
build_record(FltRecordWriter &writer) const {
if (!FltRecord::build_record(writer)) {
return false;
}
writer.set_opcode(FO_vertex_list);
Datagram &datagram = writer.update_datagram();
Vertices::const_iterator vi;
for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
datagram.add_be_uint32(_header->get_offset_by_vertex(*vi));
}
return true;
}

View File

@ -0,0 +1,61 @@
// Filename: fltVertexList.h
// Created by: drose (25Aug00)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTVERTEXLIST_H
#define FLTVERTEXLIST_H
#include <pandatoolbase.h>
#include "fltRecord.h"
#include "fltPackedColor.h"
#include "fltVertex.h"
#include <pointerTo.h>
////////////////////////////////////////////////////////////////////
// Class : FltVertexList
// Description : A list of vertices, typically added as a child of a
// face bead.
////////////////////////////////////////////////////////////////////
class FltVertexList : public FltRecord {
public:
FltVertexList(FltHeader *header);
int get_num_vertices() const;
FltVertex *get_vertex(int n) const;
void clear_vertices();
void add_vertex(FltVertex *vertex);
virtual void output(ostream &out) const;
protected:
virtual bool extract_record(FltRecordReader &reader);
virtual bool build_record(FltRecordWriter &writer) const;
private:
typedef vector<PT(FltVertex)> Vertices;
Vertices _vertices;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
FltRecord::init_type();
register_type(_type_handle, "FltVertexList",
FltRecord::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#endif

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