*** empty log message ***

This commit is contained in:
David Rose 2001-02-28 23:55:58 +00:00
parent 5fe8e52b43
commit b1046f60ec
52 changed files with 1830 additions and 425 deletions

View File

@ -8,13 +8,18 @@
#define SOURCES \
config_flt.cxx config_flt.h fltBead.cxx fltBead.h fltBeadID.cxx \
fltBeadID.h fltError.cxx fltError.h fltExternalReference.cxx \
fltBeadID.h fltCurve.I fltCurve.cxx fltCurve.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 \
fltFace.cxx fltFace.h fltGeometry.I fltGeometry.cxx fltGeometry.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 \
fltLocalVertexPool.I fltLocalVertexPool.cxx fltLocalVertexPool.h \
fltMaterial.cxx fltMaterial.h fltMesh.I fltMesh.cxx fltMesh.h \
fltMeshPrimitive.I fltMeshPrimitive.cxx fltMeshPrimitive.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 \
@ -31,10 +36,15 @@
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 \
fltBead.h fltBeadID.h fltCurve.I fltCurve.h \
fltError.h fltExternalReference.h \
fltEyepoint.h fltFace.I fltFace.h fltGeometry.I fltGeometry.h \
fltGroup.h fltHeader.h \
fltInstanceDefinition.h fltInstanceRef.h fltLOD.h \
fltLightSourceDefinition.h fltMaterial.h fltObject.h fltOpcode.h \
fltLightSourceDefinition.h fltLocalVertexPool.I fltLocalVertexPool.h \
fltMaterial.h fltMesh.I fltMesh.h \
fltMeshPrimitive.I fltMeshPrimitive.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 \

View File

@ -9,7 +9,12 @@
#include "fltBeadID.h"
#include "fltGroup.h"
#include "fltObject.h"
#include "fltGeometry.h"
#include "fltFace.h"
#include "fltCurve.h"
#include "fltMesh.h"
#include "fltLocalVertexPool.h"
#include "fltMeshPrimitive.h"
#include "fltVertexList.h"
#include "fltLOD.h"
#include "fltInstanceDefinition.h"
@ -48,7 +53,12 @@ ConfigureFn(config_flt) {
FltBeadID::init_type();
FltGroup::init_type();
FltObject::init_type();
FltGeometry::init_type();
FltFace::init_type();
FltCurve::init_type();
FltMesh::init_type();
FltLocalVertexPool::init_type();
FltMeshPrimitive::init_type();
FltVertexList::init_type();
FltLOD::init_type();
FltInstanceDefinition::init_type();

View File

@ -229,7 +229,9 @@ extract_ancillary(FltRecordReader &reader) {
// A transform step.
nassertr(step != (FltTransformRecord *)NULL, false);
step->extract_record(reader);
if (!step->extract_record(reader)) {
return false;
}
_transform_steps.push_back(DCAST(FltTransformRecord, step));
/*
@ -305,7 +307,7 @@ extract_transform_matrix(FltRecordReader &reader) {
matrix(r, c) = iterator.get_be_float32();
}
}
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
_transform_steps.clear();
_has_transform = true;
@ -327,8 +329,7 @@ extract_replicate_count(FltRecordReader &reader) {
_replicate_count = iterator.get_be_int16();
iterator.skip_bytes(2);
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -0,0 +1,30 @@
// Filename: fltCurve.I
// Created by: drose (28Feb01)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: FltCurve::get_num_control_points
// Access: Public
// Description: Returns the number of control points assigned to the
// curve.
////////////////////////////////////////////////////////////////////
INLINE int FltCurve::
get_num_control_points() const {
return _control_points.size();
}
////////////////////////////////////////////////////////////////////
// Function: FltCurve::get_control_point
// Access: Public
// Description: Returns the nth control point assigned to the curve.
////////////////////////////////////////////////////////////////////
INLINE const LPoint3d &FltCurve::
get_control_point(int n) const {
#ifndef NDEBUG
static LPoint3d bogus(0.0, 0.0, 0.0);
nassertr(n >= 0 && n < (int)_control_points.size(), bogus);
#endif
return _control_points[n];
}

View File

@ -0,0 +1,88 @@
// Filename: fltCurve.cxx
// Created by: drose (28Feb01)
//
////////////////////////////////////////////////////////////////////
#include "fltCurve.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
#include "fltHeader.h"
#include "fltMaterial.h"
TypeHandle FltCurve::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltCurve::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltCurve::
FltCurve(FltHeader *header) : FltBeadID(header) {
_curve_type = CT_b_spline;
}
////////////////////////////////////////////////////////////////////
// Function: FltCurve::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 FltCurve::
extract_record(FltRecordReader &reader) {
if (!FltBeadID::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_curve, false);
DatagramIterator &iterator = reader.get_iterator();
iterator.skip_bytes(4);
_curve_type = (CurveType)iterator.get_be_int32();
int num_control_points = iterator.get_be_int32();
iterator.skip_bytes(8);
for (int i = 0; i < num_control_points; i++) {
double x = iterator.get_be_float64();
double y = iterator.get_be_float64();
double z = iterator.get_be_float64();
_control_points.push_back(LPoint3d(x, y, z));
}
check_remaining_size(iterator);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltCurve::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 FltCurve::
build_record(FltRecordWriter &writer) const {
if (!FltBeadID::build_record(writer)) {
return false;
}
writer.set_opcode(FO_curve);
Datagram &datagram = writer.update_datagram();
datagram.pad_bytes(4);
datagram.add_be_int32(_curve_type);
datagram.add_be_int32(_control_points.size());
datagram.pad_bytes(8);
ControlPoints::const_iterator ci;
for (ci = _control_points.begin(); ci != _control_points.end(); ++ci) {
const LPoint3d &p = (*ci);
datagram.add_be_float64(p[0]);
datagram.add_be_float64(p[1]);
datagram.add_be_float64(p[2]);
}
return true;
}

View File

@ -0,0 +1,66 @@
// Filename: fltCurve.h
// Created by: drose (28Feb01)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTCURVE_H
#define FLTCURVE_H
#include <pandatoolbase.h>
#include "fltBeadID.h"
#include "fltHeader.h"
#include <luse.h>
////////////////////////////////////////////////////////////////////
// Class : FltCurve
// Description : A single curve, like a Bezier or B-Spline.
////////////////////////////////////////////////////////////////////
class FltCurve : public FltBeadID {
public:
FltCurve(FltHeader *header);
enum CurveType {
CT_b_spline = 4,
CT_cardinal = 5,
CT_bezier = 6
};
typedef vector<LPoint3d> ControlPoints;
CurveType _curve_type;
ControlPoints _control_points;
public:
INLINE int get_num_control_points() const;
INLINE const LPoint3d &get_control_point(int n) 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, "FltCurve",
FltBeadID::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "fltCurve.I"
#endif

View File

@ -86,7 +86,7 @@ extract_record(FltRecordReader &reader) {
}
}
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -3,58 +3,3 @@
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// 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

@ -17,125 +17,7 @@ TypeHandle FltFace::_type_handle;
// 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);
FltFace(FltHeader *header) : FltGeometry(header) {
}
////////////////////////////////////////////////////////////////////
@ -151,46 +33,14 @@ extract_record(FltRecordReader &reader) {
if (!FltBeadID::extract_record(reader)) {
return false;
}
if (!FltGeometry::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);
check_remaining_size(iterator);
return true;
}
@ -207,44 +57,11 @@ build_record(FltRecordWriter &writer) const {
if (!FltBeadID::build_record(writer)) {
return false;
}
if (!FltGeometry::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;
}

View File

@ -8,96 +8,16 @@
#include <pandatoolbase.h>
#include "fltBeadID.h"
#include "fltPackedColor.h"
#include "fltHeader.h"
#include <luse.h>
class FltTexture;
class FltMaterial;
#include "fltGeometry.h"
////////////////////////////////////////////////////////////////////
// Class : FltFace
// Description : A single face bead, e.g. a polygon.
////////////////////////////////////////////////////////////////////
class FltFace : public FltBeadID {
class FltFace : public FltGeometry {
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);
@ -112,9 +32,9 @@ public:
return _type_handle;
}
static void init_type() {
FltBeadID::init_type();
FltGeometry::init_type();
register_type(_type_handle, "FltFace",
FltBeadID::get_class_type());
FltGeometry::get_class_type());
}
private:

View File

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

View File

@ -0,0 +1,239 @@
// Filename: fltGeometry.cxx
// Created by: drose (28Feb01)
//
////////////////////////////////////////////////////////////////////
#include "fltGeometry.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
#include "fltHeader.h"
#include "fltMaterial.h"
TypeHandle FltGeometry::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltGeometry::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltGeometry::
FltGeometry(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: FltGeometry::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 FltGeometry::
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: FltGeometry::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 FltGeometry::
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: FltGeometry::has_alt_color
// Access: Public
// Description: Returns true if the face has an alternate color
// indicated, false otherwise.
////////////////////////////////////////////////////////////////////
bool FltGeometry::
has_alt_color() const {
return (_flags & F_no_alt_color) == 0;
}
////////////////////////////////////////////////////////////////////
// Function: FltGeometry::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 FltGeometry::
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: FltGeometry::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 FltGeometry::
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: FltGeometry::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 FltGeometry::
extract_record(FltRecordReader &reader) {
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);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltGeometry::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 FltGeometry::
build_record(FltRecordWriter &writer) const {
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;
}

View File

@ -0,0 +1,131 @@
// Filename: fltGeometry.h
// Created by: drose (28Feb01)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTGEOMETRY_H
#define FLTGEOMETRY_H
#include <pandatoolbase.h>
#include "fltBeadID.h"
#include "fltPackedColor.h"
#include "fltHeader.h"
#include <luse.h>
class FltTexture;
class FltMaterial;
////////////////////////////////////////////////////////////////////
// Class : FltGeometry
// Description : This is a base class for both FltFace and FltMesh,
// which are two different kinds of geometric primitives
// that might be encountered in a MultiGen file. They
// have similar properties.
////////////////////////////////////////////////////////////////////
class FltGeometry : public FltBeadID {
public:
FltGeometry(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, "FltGeometry",
FltBeadID::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "fltGeometry.I"
#endif

View File

@ -50,7 +50,7 @@ extract_record(FltRecordReader &reader) {
_layer_id = iterator.get_int8();
iterator.skip_bytes(5);
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -20,8 +20,8 @@ TypeHandle FltHeader::_type_handle;
////////////////////////////////////////////////////////////////////
FltHeader::
FltHeader() : FltBeadID(this) {
_format_revision_level = 1520;
_edit_revision_level = 1520;
_format_revision_level = 1570;
_edit_revision_level = 1570;
_next_group_id = 1;
_next_lod_id = 1;
_next_object_id = 1;
@ -57,6 +57,15 @@ FltHeader() : FltBeadID(this) {
_next_cat_id = 1;
_earth_model = EM_wgs84;
// New with 15.6
_next_adaptive_id = 0;
_next_curve_id = 0;
// New with 15.7
_delta_z = 0.0;
_radius = 0.0;
_next_mesh_id = 0;
_vertex_lookups_stale = false;
_current_vertex_offset = 0;
_got_color_palette = false;
@ -239,15 +248,15 @@ min_flt_version() {
////////////////////////////////////////////////////////////////////
double FltHeader::
max_flt_version() {
return 15.2;
return 15.7;
}
////////////////////////////////////////////////////////////////////
// Function: FltHeader::check_version
// Access: Public
// Description: Verifies that the version number read from the header
// is an understand version number, and prints a warning
// to the user if this is not so--the reading may or may
// is an understood version number, and prints a warning
// to the user if this is not so--the read may or may
// not succeed. Returns true if the version number is
// acceptable (and no warning is printed), or false if
// it is questionable (and a warning is printed).
@ -593,7 +602,7 @@ get_closest_color(Colorf color) const {
}
////////////////////////////////////////////////////////////////////
// Function: FltHeader::get_closest_color
// Function: FltHeader::get_closest_rgb
// Access: Public
// Description: Returns the color index of the nearest color in the
// palette that matches the given three-component color,
@ -1144,10 +1153,26 @@ extract_record(FltRecordReader &reader) {
iterator.skip_bytes(2 + 2 + 2 + 2);
_earth_model = (EarthModel)iterator.get_be_int32();
// Undocumented additional padding.
// Undocumented padding.
iterator.skip_bytes(4);
// nassertr(iterator.get_remaining_size() == 0, true);
if (get_flt_version() >= 15.6 && iterator.get_remaining_size() > 0) {
_next_adaptive_id = iterator.get_be_int16();
_next_curve_id = iterator.get_be_int16();
iterator.skip_bytes(4);
if (get_flt_version() >= 15.7 && iterator.get_remaining_size() > 0) {
_delta_z = iterator.get_be_float64();
_radius = iterator.get_be_float64();
_next_mesh_id = iterator.get_be_int16();
iterator.skip_bytes(2);
// Undocumented padding.
iterator.skip_bytes(4);
}
}
check_remaining_size(iterator);
return true;
}
@ -1260,8 +1285,23 @@ build_record(FltRecordWriter &writer) const {
datagram.pad_bytes(2 + 2 + 2 + 2);
datagram.add_be_int32(_earth_model);
// Undocumented additional padding.
datagram.pad_bytes(4);
datagram.pad_bytes(4);
if (get_flt_version() >= 15.6) {
// New with 15.6
datagram.add_be_int16(_next_adaptive_id);
datagram.add_be_int16(_next_curve_id);
datagram.pad_bytes(4);
if (get_flt_version() >= 15.7) {
// New with 15.7
datagram.add_be_float64(_delta_z);
datagram.add_be_float64(_radius);
datagram.add_be_int16(_next_mesh_id);
datagram.pad_bytes(2);
datagram.pad_bytes(4);
}
}
return true;
}
@ -1377,7 +1417,7 @@ extract_color_palette(FltRecordReader &reader) {
_color_names[color_index] = iterator.get_fixed_string(name_length);
}
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}
@ -1479,7 +1519,7 @@ extract_eyepoint_palette(FltRecordReader &reader) {
}
_got_eyepoint_trackplane_palette = true;
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -120,6 +120,11 @@ public:
int _next_road_id;
int _next_cat_id;
EarthModel _earth_model;
int _next_adaptive_id;
int _next_curve_id;
double _delta_z;
double _radius;
int _next_mesh_id;
public:
double get_flt_version() const;

View File

@ -39,7 +39,7 @@ extract_record(FltRecordReader &reader) {
iterator.skip_bytes(2);
_instance_index = iterator.get_be_int16();
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -61,7 +61,7 @@ extract_record(FltRecordReader &reader) {
iterator.skip_bytes(2);
_instance_index = iterator.get_be_int16();
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -55,7 +55,7 @@ extract_record(FltRecordReader &reader) {
_center_z = iterator.get_be_float64();
_transition_range = iterator.get_be_float64();
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -76,7 +76,7 @@ extract_record(FltRecordReader &reader) {
_modeling_light = (iterator.get_be_int32() != 0);
iterator.skip_bytes(4*19);
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -0,0 +1,4 @@
// Filename: fltLocalVertexPool.I
// Created by: drose (28Feb01)
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,235 @@
// Filename: fltLocalVertexPool.cxx
// Created by: drose (28Feb01)
//
////////////////////////////////////////////////////////////////////
#include "fltLocalVertexPool.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
#include "fltHeader.h"
#include "fltMaterial.h"
TypeHandle FltLocalVertexPool::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltLocalVertexPool::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltLocalVertexPool::
FltLocalVertexPool(FltHeader *header) : FltRecord(header) {
}
////////////////////////////////////////////////////////////////////
// Function: FltLocalVertexPool::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 FltLocalVertexPool::
extract_record(FltRecordReader &reader) {
if (!FltRecord::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_local_vertex_pool, false);
DatagramIterator &iterator = reader.get_iterator();
int num_vertices = iterator.get_be_int32();
int attributes = iterator.get_be_int32();
for (int i = 0; i < num_vertices; i++) {
FltVertex *vertex = new FltVertex(_header);
_vertices.push_back(vertex);
if ((attributes & AM_has_position) != 0) {
vertex->_pos[0] = iterator.get_be_float64();
vertex->_pos[1] = iterator.get_be_float64();
vertex->_pos[2] = iterator.get_be_float64();
}
if ((attributes & AM_has_color_index) != 0) {
vertex->_color_index = iterator.get_be_int32();
} else if ((attributes & AM_has_packed_color) != 0) {
if (!vertex->_packed_color.extract_record(reader)) {
return false;
}
vertex->_flags |= FltVertex::F_packed_color;
} else {
vertex->_flags |= FltVertex::F_no_color;
}
if ((attributes & AM_has_normal) != 0) {
vertex->_normal[0] = iterator.get_be_float32();
vertex->_normal[1] = iterator.get_be_float32();
vertex->_normal[2] = iterator.get_be_float32();
vertex->_has_normal = true;
}
if ((attributes & AM_has_base_uv) != 0) {
vertex->_uv[0] = iterator.get_be_float32();
vertex->_uv[1] = iterator.get_be_float32();
vertex->_has_uv = true;
}
if ((attributes & AM_has_uv_1) != 0) {
iterator.get_be_float32();
iterator.get_be_float32();
}
if ((attributes & AM_has_uv_2) != 0) {
iterator.get_be_float32();
iterator.get_be_float32();
}
if ((attributes & AM_has_uv_3) != 0) {
iterator.get_be_float32();
iterator.get_be_float32();
}
if ((attributes & AM_has_uv_4) != 0) {
iterator.get_be_float32();
iterator.get_be_float32();
}
if ((attributes & AM_has_uv_5) != 0) {
iterator.get_be_float32();
iterator.get_be_float32();
}
if ((attributes & AM_has_uv_6) != 0) {
iterator.get_be_float32();
iterator.get_be_float32();
}
if ((attributes & AM_has_uv_7) != 0) {
iterator.get_be_float32();
iterator.get_be_float32();
}
}
check_remaining_size(iterator);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltLocalVertexPool::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 FltLocalVertexPool::
build_record(FltRecordWriter &writer) const {
if (!FltRecord::build_record(writer)) {
return false;
}
writer.set_opcode(FO_local_vertex_pool);
Datagram &datagram = writer.update_datagram();
// Determine what kind of vertices we have.
int attributes = AM_has_position;
Vertices::const_iterator vi;
for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
FltVertex *vertex = (*vi);
if ((vertex->_flags & FltVertex::F_no_color) != 0) {
// No color.
} else if ((vertex->_flags & FltVertex::F_packed_color) != 0) {
// Packed color.
attributes |= AM_has_packed_color;
} else {
// Indexed color.
attributes |= AM_has_color_index;
}
if (vertex->_has_normal) {
attributes |= AM_has_normal;
}
if (vertex->_has_uv) {
attributes |= AM_has_base_uv;
}
}
if ((attributes & AM_has_packed_color) != 0 &&
(attributes & AM_has_color_index) != 0) {
// We cannot have both a packed color and a color index. If we
// want both, used packed color.
attributes &= ~AM_has_color_index;
}
datagram.add_be_int32(_vertices.size());
datagram.add_be_int32(attributes);
// Now write out each vertex.
for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
FltVertex *vertex = (*vi);
if ((attributes & AM_has_position) != 0) {
datagram.add_be_float64(vertex->_pos[0]);
datagram.add_be_float64(vertex->_pos[1]);
datagram.add_be_float64(vertex->_pos[2]);
}
if ((attributes & AM_has_color_index) != 0) {
if ((vertex->_flags & (FltVertex::F_no_color | FltVertex::F_packed_color)) != 0) {
// This particular vertex does not have a color index.
// Make it white.
datagram.add_be_int32(_header->get_closest_rgb(RGBColorf(1.0, 1.0, 1.0)));
} else {
datagram.add_be_int32(vertex->_color_index);
}
} else if ((attributes & AM_has_packed_color) != 0) {
// We extract our own FltPackedColor instead of writing out the
// vertex's _packed_color directly, just in case the vertex is
// actually index colored. This bit of code will work
// regardless of the kind of color the vertex has.
FltPackedColor color;
if (vertex->has_color()) {
color.set_color(vertex->get_color());
} else {
// An uncolored vertex. Make it white.
color.set_color(Colorf(1.0, 1.0, 1.0, 1.0));
}
if (!color.build_record(writer)) {
return false;
}
}
if ((attributes & AM_has_normal) != 0) {
if (!vertex->_has_normal) {
datagram.add_be_float32(0.0);
datagram.add_be_float32(0.0);
datagram.add_be_float32(0.0);
} else {
datagram.add_be_float32(vertex->_normal[0]);
datagram.add_be_float32(vertex->_normal[1]);
datagram.add_be_float32(vertex->_normal[2]);
}
}
if ((attributes & AM_has_base_uv) != 0) {
if (!vertex->_has_uv) {
datagram.add_be_float32(0.0);
datagram.add_be_float32(0.0);
} else {
datagram.add_be_float32(vertex->_uv[0]);
datagram.add_be_float32(vertex->_uv[1]);
}
}
}
return true;
}

View File

@ -0,0 +1,72 @@
// Filename: fltLocalVertexPool.h
// Created by: drose (28Feb01)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTLOCALVERTEXPOOL_H
#define FLTLOCALVERTEXPOOL_H
#include <pandatoolbase.h>
#include "fltRecord.h"
#include "fltHeader.h"
#include "fltVertex.h"
#include <pointerTo.h>
////////////////////////////////////////////////////////////////////
// Class : FltLocalVertexPool
// Description : A local vertex pool, as might appear in the middle of
// the hierarchy, for instance for a mesh.
////////////////////////////////////////////////////////////////////
class FltLocalVertexPool : public FltRecord {
public:
FltLocalVertexPool(FltHeader *header);
// These bits are not stored in the vertex pool, but are read from
// the .flt file and used immediately.
enum AttributeMask {
AM_has_position = 0x80000000,
AM_has_color_index = 0x40000000,
AM_has_packed_color = 0x20000000,
AM_has_normal = 0x10000000,
AM_has_base_uv = 0x08000000,
AM_has_uv_1 = 0x04000000,
AM_has_uv_2 = 0x02000000,
AM_has_uv_3 = 0x01000000,
AM_has_uv_4 = 0x00800000,
AM_has_uv_5 = 0x00400000,
AM_has_uv_6 = 0x00200000,
AM_has_uv_7 = 0x00100000
};
typedef vector<PT(FltVertex)> Vertices;
Vertices _vertices;
public:
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, "FltLocalVertexPool",
FltRecord::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "fltLocalVertexPool.I"
#endif

View File

@ -62,7 +62,7 @@ extract_record(FltRecordReader &reader) {
_alpha = iterator.get_be_float32();
iterator.skip_bytes(4);
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -0,0 +1,4 @@
// Filename: fltMesh.I
// Created by: drose (28Feb01)
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,118 @@
// Filename: fltMesh.cxx
// Created by: drose (28Feb01)
//
////////////////////////////////////////////////////////////////////
#include "fltMesh.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
#include "fltHeader.h"
#include "fltMaterial.h"
#include "config_flt.h"
TypeHandle FltMesh::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltMesh::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltMesh::
FltMesh(FltHeader *header) : FltGeometry(header) {
}
////////////////////////////////////////////////////////////////////
// Function: FltMesh::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 FltMesh::
extract_record(FltRecordReader &reader) {
if (!FltBeadID::extract_record(reader)) {
return false;
}
DatagramIterator &iterator = reader.get_iterator();
iterator.skip_bytes(4); // Undocumented padding.
if (!FltGeometry::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_mesh, false);
check_remaining_size(iterator);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltMesh::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 FltMesh::
extract_ancillary(FltRecordReader &reader) {
if (reader.get_opcode() == FO_local_vertex_pool) {
_vpool = new FltLocalVertexPool(_header);
return _vpool->extract_record(reader);
}
return FltBeadID::extract_ancillary(reader);
}
////////////////////////////////////////////////////////////////////
// Function: FltMesh::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 FltMesh::
build_record(FltRecordWriter &writer) const {
if (!FltBeadID::build_record(writer)) {
return false;
}
Datagram &datagram = writer.update_datagram();
datagram.pad_bytes(4); // Undocumented padding.
if (!FltGeometry::build_record(writer)) {
return false;
}
writer.set_opcode(FO_mesh);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltMesh::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 FltMesh::
write_ancillary(FltRecordWriter &writer) const {
if (_vpool != (FltLocalVertexPool *)NULL) {
if (!_vpool->build_record(writer)) {
assert(!flt_error_abort);
return FE_bad_data;
}
FltError result = writer.advance();
if (result != FE_ok) {
return result;
}
}
return FltBeadID::write_ancillary(writer);
}

View File

@ -0,0 +1,56 @@
// Filename: fltMesh.h
// Created by: drose (28Feb01)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTMESH_H
#define FLTMESH_H
#include <pandatoolbase.h>
#include "fltGeometry.h"
#include "fltLocalVertexPool.h"
#include <pointerTo.h>
////////////////////////////////////////////////////////////////////
// Class : FltMesh
// Description : A mesh of connected polygons and tristrips, etc.,
// with a local vertex pool.
////////////////////////////////////////////////////////////////////
class FltMesh : public FltGeometry {
public:
FltMesh(FltHeader *header);
PT(FltLocalVertexPool) _vpool;
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;
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() {
FltGeometry::init_type();
register_type(_type_handle, "FltMesh",
FltGeometry::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "fltMesh.I"
#endif

View File

@ -0,0 +1,4 @@
// Filename: fltMeshPrimitive.I
// Created by: drose (28Feb01)
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,127 @@
// Filename: fltMeshPrimitive.cxx
// Created by: drose (28Feb01)
//
////////////////////////////////////////////////////////////////////
#include "fltMeshPrimitive.h"
#include "fltRecordReader.h"
#include "fltRecordWriter.h"
#include "fltHeader.h"
#include "fltMaterial.h"
TypeHandle FltMeshPrimitive::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FltMeshPrimitive::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltMeshPrimitive::
FltMeshPrimitive(FltHeader *header) : FltBead(header) {
_primitive_type = PT_tristrip;
}
////////////////////////////////////////////////////////////////////
// Function: FltMeshPrimitive::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 FltMeshPrimitive::
extract_record(FltRecordReader &reader) {
if (!FltBead::extract_record(reader)) {
return false;
}
nassertr(reader.get_opcode() == FO_mesh_primitive, false);
DatagramIterator &iterator = reader.get_iterator();
_primitive_type = (PrimitiveType)iterator.get_be_int16();
int vertex_width = iterator.get_be_int16();
int num_vertices = iterator.get_be_int32();
if (vertex_width == 1) {
for (int i = 0; i < num_vertices; i++) {
_vertices.push_back(iterator.get_uint8());
}
} else if (vertex_width == 2) {
for (int i = 0; i < num_vertices; i++) {
_vertices.push_back(iterator.get_be_uint16());
}
} else if (vertex_width == 4) {
for (int i = 0; i < num_vertices; i++) {
_vertices.push_back(iterator.get_be_int32());
}
} else {
nout << "Invalid vertex width in mesh primitive: " << vertex_width
<< "\n";
return false;
}
check_remaining_size(iterator);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: FltMeshPrimitive::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 FltMeshPrimitive::
build_record(FltRecordWriter &writer) const {
if (!FltBead::build_record(writer)) {
return false;
}
writer.set_opcode(FO_mesh_primitive);
Datagram &datagram = writer.update_datagram();
datagram.add_be_int16(_primitive_type);
// Determine the optimum index width, based on the largest vertex
// index.
int max_index = 0;
Vertices::const_iterator vi;
for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
max_index = max(max_index, (*vi));
}
int vertex_width;
if (max_index < 0x100) {
vertex_width = 1;
} else if (max_index < 0x10000) {
vertex_width = 2;
} else {
vertex_width = 4;
}
datagram.add_be_int16(vertex_width);
datagram.add_be_int32(_vertices.size());
if (vertex_width == 1) {
for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
datagram.add_uint8(*vi);
}
} else if (vertex_width == 2) {
for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
datagram.add_be_uint16(*vi);
}
} else {
for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
datagram.add_be_int32(*vi);
}
}
return true;
}

View File

@ -0,0 +1,64 @@
// Filename: fltMeshPrimitive.h
// Created by: drose (28Feb01)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTMESHPRIMITIVE_H
#define FLTMESHPRIMITIVE_H
#include <pandatoolbase.h>
#include "fltBead.h"
#include "fltHeader.h"
#include <luse.h>
////////////////////////////////////////////////////////////////////
// Class : FltMeshPrimitive
// Description : A single primitive of a mesh, like a triangle strip
// or fan.
////////////////////////////////////////////////////////////////////
class FltMeshPrimitive : public FltBead {
public:
FltMeshPrimitive(FltHeader *header);
enum PrimitiveType {
PT_tristrip = 1,
PT_trifan = 2,
PT_quadstrip = 3,
PT_polygon = 4,
};
typedef vector<int> Vertices;
PrimitiveType _primitive_type;
Vertices _vertices;
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, "FltMeshPrimitive",
FltBead::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "fltMeshPrimitive.I"
#endif

View File

@ -43,7 +43,7 @@ extract_record(FltRecordReader &reader) {
_significance = iterator.get_be_int16();
iterator.skip_bytes(2);
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -69,6 +69,15 @@ operator << (ostream &out, FltOpcode opcode) {
case FO_pop_face:
return out << "pop subface";
case FO_push_extension:
return out << "push extension";
case FO_pop_extension:
return out << "pop extension";
case FO_continuation:
return out << "continuation";
case FO_comment:
return out << "comment";
@ -103,6 +112,12 @@ operator << (ostream &out, FltOpcode opcode) {
case FO_vector:
return out << "vector";
case FO_multitexture:
return out << "multitexture";
case FO_uv_list:
return out << "UV list";
case FO_bsp:
return out << "BSP";
@ -172,6 +187,15 @@ operator << (ostream &out, FltOpcode opcode) {
case FO_eyepoint_palette:
return out << "eyepoint palette";
case FO_mesh:
return out << "mesh";
case FO_local_vertex_pool:
return out << "local vertex pool";
case FO_mesh_primitive:
return out << "mesh primitive";
case FO_road_segment:
return out << "road segment";
@ -226,14 +250,17 @@ operator << (ostream &out, FltOpcode opcode) {
case FO_bv_orientation:
return out << "bounding volume orientation";
case FO_light_point:
return out << "light point";
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_name_table:
return out << "name table";
case FO_cat:
return out << "continuously adaptive terrain";
@ -247,6 +274,15 @@ operator << (ostream &out, FltOpcode opcode) {
case FO_pop_attribute:
return out << "pop attribute";
case FO_adaptive_attribute:
return out << "adaptive attribute";
case FO_curve:
return out << "curve";
case FO_road_construction:
return out << "road construction";
default:
return out << "unknown opcode " << (int)opcode;
}

View File

@ -29,6 +29,10 @@ enum FltOpcode {
FO_OB_instance = 17, // obsolete
FO_push_face = 19,
FO_pop_face = 20,
FO_push_extension = 21,
FO_pop_extension = 22,
FO_continuation = 23,
FO_comment = 31,
FO_color_palette = 32,
FO_long_id = 33,
@ -44,6 +48,8 @@ enum FltOpcode {
FO_transform_matrix = 49,
FO_vector = 50,
FO_OB_bounding_box = 51, // obsolete
FO_multitexture = 52,
FO_uv_list = 53,
FO_bsp = 55,
FO_replicate = 60,
FO_instance_ref = 61,
@ -68,6 +74,9 @@ enum FltOpcode {
FO_rotate_and_scale = 81,
FO_put = 82,
FO_eyepoint_palette = 83,
FO_mesh = 84,
FO_local_vertex_pool = 85,
FO_mesh_primitive = 86,
FO_road_segment = 87,
FO_road_zone = 88,
FO_morph_list = 89,
@ -80,19 +89,24 @@ enum FltOpcode {
FO_switch = 96,
FO_line_style = 97,
FO_clip_region = 98,
FO_extension = 100,
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_light_point = 111,
FO_texture_map_palette = 112,
FO_15_material = 113,
FO_color_name_palette = 114,
FO_name_table = 114,
FO_cat = 115,
FO_cat_data = 116,
FO_push_attribute = 122,
FO_pop_attribute = 123,
FO_adaptive_attribute = 125,
FO_curve = 126,
FO_road_construction = 127
};
ostream &operator << (ostream &out, FltOpcode opcode);

View File

@ -45,3 +45,32 @@ INLINE RGBColorf FltPackedColor::
get_rgb() const {
return RGBColorf(_r / 255.0, _g / 255.0, _b / 255.0);
}
////////////////////////////////////////////////////////////////////
// Function: FltPackedColor::set_color
// Access: Public
// Description: Sets the color according to the indicated
// four-component Colorf value (including alpha).
////////////////////////////////////////////////////////////////////
INLINE void FltPackedColor::
set_color(const Colorf &color) {
_r = (int)floor(color[0] * 255.0);
_g = (int)floor(color[0] * 255.0);
_b = (int)floor(color[0] * 255.0);
_a = (int)floor(color[0] * 255.0);
}
////////////////////////////////////////////////////////////////////
// Function: FltPackedColor::set_rgb
// Access: Public
// Description: Sets the color according to the indicated
// three-component RGBColorf value, and set the alpha to
// 1.0.
////////////////////////////////////////////////////////////////////
INLINE void FltPackedColor::
set_rgb(const RGBColorf &color) {
_r = (int)floor(color[0] * 255.0);
_g = (int)floor(color[0] * 255.0);
_b = (int)floor(color[0] * 255.0);
_a = 255;
}

View File

@ -9,6 +9,7 @@
#include <pandatoolbase.h>
#include <luse.h>
#include <math.h>
class FltRecordReader;
class FltRecordWriter;
@ -24,6 +25,8 @@ public:
INLINE Colorf get_color() const;
INLINE RGBColorf get_rgb() const;
INLINE void set_color(const Colorf &color);
INLINE void set_rgb(const RGBColorf &rgb);
void output(ostream &out) const;
bool extract_record(FltRecordReader &reader);

View File

@ -10,6 +10,10 @@
#include "fltGroup.h"
#include "fltObject.h"
#include "fltFace.h"
#include "fltCurve.h"
#include "fltMesh.h"
#include "fltLocalVertexPool.h"
#include "fltMeshPrimitive.h"
#include "fltVertexList.h"
#include "fltLOD.h"
#include "fltInstanceDefinition.h"
@ -19,6 +23,7 @@
#include "config_flt.h"
#include <indent.h>
#include <datagramIterator.h>
#include <assert.h>
@ -132,6 +137,52 @@ add_subface(FltRecord *subface) {
_subfaces.push_back(subface);
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::get_num_extensions
// Access: Public
// Description: Returns the number of extension attribute records for
// this object. These are auxiliary nodes, presumably
// of type FO_extension, that have some local meaning to
// the object.
////////////////////////////////////////////////////////////////////
int FltRecord::
get_num_extensions() const {
return _extensions.size();
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::get_extension
// Access: Public
// Description: Returns the nth extension of this record.
////////////////////////////////////////////////////////////////////
FltRecord *FltRecord::
get_extension(int n) const {
nassertr(n >= 0 && n < (int)_extensions.size(), (FltRecord *)NULL);
return _extensions[n];
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::clear_extensions
// Access: Public
// Description: Removes all extensions from this record.
////////////////////////////////////////////////////////////////////
void FltRecord::
clear_extensions() {
_extensions.clear();
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::add_extension
// Access: Public
// Description: Adds a new extension to the end of the list of
// extensions for this record. This should be a record
// of type FO_extension.
////////////////////////////////////////////////////////////////////
void FltRecord::
add_extension(FltRecord *extension) {
_extensions.push_back(extension);
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::get_num_ancillary
// Access: Public
@ -233,6 +284,31 @@ set_comment(const string &comment) {
_comment = comment;
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::check_remaining_size
// Access: Public
// Description: Checks that the iterator has no bytes left, as it
// should at the end of a successfully read record. If
// there *are* remaining bytes, print a warning message
// but otherwise don't worry about it.
//
// If we are attempting to read a flt file whose version
// is newer than the newest this program understands,
// don't even print a warning message, since this is
// exactly the sort of thing we expect.
////////////////////////////////////////////////////////////////////
void FltRecord::
check_remaining_size(const DatagramIterator &iterator) const {
if (iterator.get_remaining_size() == 0) {
return;
}
if (_header->get_flt_version() <= _header->max_flt_version()) {
nout << "Warning! Ignoring extra " << iterator.get_remaining_size()
<< " bytes at the end of a " << get_type() << " record.\n";
}
}
////////////////////////////////////////////////////////////////////
// Function: FltRecord::output
// Access: Public
@ -272,6 +348,9 @@ write_children(ostream &out, int indent_level) const {
if (!_ancillary.empty()) {
out << " + " << _ancillary.size() << " ancillary";
}
if (!_extensions.empty()) {
out << " + " << _extensions.size() << " extensions";
}
if (!_subfaces.empty()) {
out << " [";
Records::const_iterator ci;
@ -313,6 +392,8 @@ is_ancillary(FltOpcode opcode) {
switch (opcode) {
case FO_comment:
case FO_long_id:
case FO_multitexture:
case FO_uv_list:
case FO_replicate:
case FO_road_zone:
case FO_transform_matrix:
@ -329,13 +410,16 @@ is_ancillary(FltOpcode opcode) {
case FO_bounding_cylinder:
case FO_bv_center:
case FO_bv_orientation:
case FO_local_vertex_pool:
case FO_cat_data:
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_name_table:
case FO_15_material:
case FO_texture:
case FO_eyepoint_palette:
@ -344,9 +428,12 @@ is_ancillary(FltOpcode opcode) {
return true;
case FO_header:
case FO_mesh:
case FO_mesh_primitive:
case FO_group:
case FO_object:
case FO_face:
case FO_light_point:
case FO_dof:
case FO_vertex_list:
case FO_morph_list:
@ -356,10 +443,14 @@ is_ancillary(FltOpcode opcode) {
case FO_sound:
case FO_light_source:
case FO_road_segment:
case FO_road_construction:
case FO_road_path:
case FO_clip_region:
case FO_text:
case FO_switch:
case FO_cat:
case FO_extension:
case FO_curve:
return false;
case FO_push:
@ -368,6 +459,8 @@ is_ancillary(FltOpcode opcode) {
case FO_pop_face:
case FO_push_attribute:
case FO_pop_attribute:
case FO_push_extension:
case FO_pop_extension:
case FO_instance:
case FO_instance_ref:
return false;
@ -397,6 +490,18 @@ create_new_record(FltOpcode opcode) const {
case FO_face:
return new FltFace(_header);
case FO_curve:
return new FltCurve(_header);
case FO_mesh:
return new FltMesh(_header);
case FO_local_vertex_pool:
return new FltLocalVertexPool(_header);
case FO_mesh_primitive:
return new FltMeshPrimitive(_header);
case FO_vertex_list:
return new FltVertexList(_header);
@ -497,6 +602,26 @@ read_record_and_children(FltRecordReader &reader) {
}
}
} else if (reader.get_opcode() == FO_push_extension) {
// A push extension begins a new list of extensions.
result = reader.advance();
if (result != FE_ok) {
return result;
}
while (reader.get_opcode() != FO_pop_extension) {
PT(FltRecord) extension = create_new_record(reader.get_opcode());
FltError result = extension->read_record_and_children(reader);
if (result != FE_ok) {
return result;
}
add_extension(extension);
if (reader.eof() || reader.error()) {
assert(!flt_error_abort);
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());
@ -602,6 +727,23 @@ write_record_and_children(FltRecordWriter &writer) const {
}
}
// Any extensions?
if (!_extensions.empty()) {
result = writer.write_record(FO_push_face);
if (result != FE_ok) {
return result;
}
for (ci = _extensions.begin(); ci != _extensions.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);

View File

@ -18,6 +18,7 @@
class FltHeader;
class FltRecordReader;
class FltRecordWriter;
class DatagramIterator;
////////////////////////////////////////////////////////////////////
// Class : FltRecord
@ -42,6 +43,11 @@ public:
void clear_subfaces();
void add_subface(FltRecord *subface);
int get_num_extensions() const;
FltRecord *get_extension(int n) const;
void clear_extensions();
void add_extension(FltRecord *extension);
int get_num_ancillary() const;
FltRecord *get_ancillary(int n) const;
void clear_ancillary();
@ -52,6 +58,8 @@ public:
void clear_comment();
void set_comment(const string &comment);
void check_remaining_size(const DatagramIterator &iterator) const;
virtual void output(ostream &out) const;
virtual void write(ostream &out, int indent_level = 0) const;
@ -76,6 +84,7 @@ private:
typedef vector<PT(FltRecord)> Records;
Records _children;
Records _subfaces;
Records _extensions;
Records _ancillary;
string _comment;

View File

@ -10,6 +10,8 @@
#include <assert.h>
static const int header_size = 4;
////////////////////////////////////////////////////////////////////
// Function: FltRecordReader::Constructor
// Access: Public
@ -23,6 +25,12 @@ FltRecordReader(istream &in) :
_record_length = 0;
_iterator = (DatagramIterator *)NULL;
_state = S_begin;
_next_error = FE_ok;
_next_opcode = FO_none;
_next_record_length = 0;
// Read the first header to get us going.
read_next_header();
}
////////////////////////////////////////////////////////////////////
@ -110,13 +118,7 @@ advance(bool ok_eof) {
_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()) {
if (_next_error == FE_end_of_file) {
_state = S_eof;
if (ok_eof) {
return FE_ok;
@ -124,30 +126,23 @@ advance(bool ok_eof) {
assert(!flt_error_abort);
return FE_end_of_file;
} else if (_in.fail()) {
} else if (_next_error != FE_ok) {
_state = S_error;
assert(!flt_error_abort);
return FE_read_error;
return _next_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();
if (_record_length < header_size) {
assert(!flt_error_abort);
return FE_invalid_record;
}
_opcode = _next_opcode;
_record_length = _next_record_length;
if (flt_cat.is_debug()) {
flt_cat.debug()
<< "Reading " << _opcode << " of length " << _record_length << "\n";
<< "Reading " << _opcode
<< " of length " << _record_length << "\n";
}
// And now read the full record based on the length.
int length = _record_length - header_size;
int length = _next_record_length - header_size;
char *buffer = new char[length];
if (length > 0) {
_in.read(buffer, length);
@ -167,6 +162,40 @@ advance(bool ok_eof) {
return FE_read_error;
}
// Check out the next header in case it's a continuation.
read_next_header();
while (_next_error == FE_ok && _next_opcode == FO_continuation) {
if (flt_cat.is_debug()) {
flt_cat.debug()
<< "Reading continuation of length " << _next_record_length << "\n";
}
// Read the continuation and tack it on.
_record_length += _next_record_length;
length = _next_record_length - header_size;
buffer = new char[length];
if (length > 0) {
_in.read(buffer, length);
}
_datagram.append_data(buffer, length);
delete[] buffer;
if (_in.eof()) {
_state = S_eof;
assert(!flt_error_abort);
return FE_end_of_file;
}
if (_in.fail()) {
_state = S_error;
assert(!flt_error_abort);
return FE_read_error;
}
read_next_header();
}
// Finally, create a new iterator to read this record.
_iterator = new DatagramIterator(_datagram);
_state = S_normal;
@ -196,3 +225,39 @@ error() const {
return _state == S_error;
}
////////////////////////////////////////////////////////////////////
// Function: FltRecordReader::read_next_header
// Access: Private
// Description: Reads the four-byte header for the next record, which
// contains the next opcode and record length.
//
// We need read the next header in advance so we can
// check to see if it happens to be a continuation
// record. If it is, we will need to concatenate the
// records together before returning.
////////////////////////////////////////////////////////////////////
void FltRecordReader::
read_next_header() {
char bytes[header_size];
_in.read(bytes, header_size);
if (_in.eof()) {
_next_error = FE_end_of_file;
return;
} else if (_in.fail()) {
_next_error = FE_read_error;
return;
}
// Now extract out the opcode and length.
Datagram dg(bytes, header_size);
DatagramIterator dgi(dg);
_next_opcode = (FltOpcode)dgi.get_be_int16();
_next_record_length = dgi.get_be_uint16();
if (_next_record_length < header_size) {
_next_error = FE_invalid_record;
return;
}
}

View File

@ -38,11 +38,17 @@ public:
bool error() const;
private:
void read_next_header();
istream &_in;
Datagram _datagram;
FltOpcode _opcode;
int _record_length;
DatagramIterator *_iterator;
FltError _next_error;
FltOpcode _next_opcode;
int _next_record_length;
enum State {
S_begin,

View File

@ -12,6 +12,13 @@
#include <assert.h>
static const int header_size = 4;
// Don't attempt to write more than this number of bytes in one
// record. If the record requires more than this, use continuation
// records.
static const int max_write_length = 65532;
////////////////////////////////////////////////////////////////////
// Function: FltRecordWriter::Constructor
// Access: Public
@ -76,33 +83,43 @@ update_datagram() {
////////////////////////////////////////////////////////////////////
FltError FltRecordWriter::
advance() {
if (flt_cat.is_debug()) {
flt_cat.debug()
<< "Writing " << _opcode << " of length "
<< _datagram.get_length() << "\n";
}
int start_byte = 0;
int write_length =
min((int)_datagram.get_length() - start_byte, max_write_length - header_size);
FltOpcode opcode = _opcode;
// Build a mini-datagram to write the header.
static const int header_size = 4;
do {
if (flt_cat.is_debug()) {
flt_cat.debug()
<< "Writing " << opcode << " of length "
<< write_length + header_size << "\n";
}
Datagram dg;
dg.add_be_int16(_opcode);
dg.add_be_int16(_datagram.get_length() + header_size);
// Build a mini-datagram to write the header.
Datagram dg;
dg.add_be_int16(opcode);
dg.add_be_int16(write_length + header_size);
nassertr((int)dg.get_length() == header_size, FE_internal);
nassertr((int)dg.get_length() == header_size, FE_internal);
_out.write(dg.get_message().data(), dg.get_length());
if (_out.fail()) {
assert(!flt_error_abort);
return FE_write_error;
}
_out.write((const char *)dg.get_data(), dg.get_length());
if (_out.fail()) {
assert(!flt_error_abort);
return FE_write_error;
}
// Now write the rest of the record.
_out.write(_datagram.get_message().data(), _datagram.get_length());
if (_out.fail()) {
assert(!flt_error_abort);
return FE_write_error;
}
// Now write the rest of the record.
_out.write((const char *)_datagram.get_data() + start_byte, write_length);
if (_out.fail()) {
assert(!flt_error_abort);
return FE_write_error;
}
start_byte += write_length;
write_length =
min((int)_datagram.get_length() - start_byte, max_write_length - header_size);
opcode = FO_continuation;
} while (write_length > 0);
_datagram.clear();
_opcode = FO_none;

View File

@ -214,7 +214,7 @@ extract_record(FltRecordReader &reader) {
nout << "Unable to read attribute file " << get_attr_filename() << "\n";
}
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}
@ -343,7 +343,19 @@ unpack_attr(const Datagram &datagram) {
}
}
nassertr(iterator.get_remaining_size() == 0, FE_ok);
if (iterator.get_remaining_size() != 0) {
int num_defs = iterator.get_be_int32();
while (num_defs > 0) {
SubtextureDef def;
def._name = iterator.get_fixed_string(32);
def._left = iterator.get_be_int32();
def._bottom = iterator.get_be_int32();
def._right = iterator.get_be_int32();
def._top = iterator.get_be_int32();
}
}
check_remaining_size(iterator);
return FE_ok;
}
@ -430,12 +442,28 @@ pack_attr(Datagram &datagram) const {
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]);
const GeospecificControlPoint &gcp = (*pi);
datagram.add_be_float64(gcp._uv[0]);
datagram.add_be_float64(gcp._uv[1]);
datagram.add_be_float64(gcp._real_earth[0]);
datagram.add_be_float64(gcp._real_earth[1]);
}
}
// Also write out the subtexture definitions.
datagram.add_be_int32(_subtexture_defs.size());
SubtextureDefs::const_iterator di;
for (di = _subtexture_defs.begin();
di != _subtexture_defs.end();
++di) {
const SubtextureDef &def = (*di);
datagram.add_fixed_string(def._name, 31);
datagram.add_int8(0);
datagram.add_be_int32(def._left);
datagram.add_be_int32(def._bottom);
datagram.add_be_int32(def._right);
datagram.add_be_int32(def._top);
}
return FE_ok;
}

View File

@ -145,6 +145,15 @@ public:
typedef vector<GeospecificControlPoint> GeospecificControlPoints;
struct SubtextureDef {
string _name;
int _left;
int _bottom;
int _right;
int _top;
};
typedef vector<SubtextureDef> SubtextureDefs;
int _num_texels_u;
int _num_texels_v;
int _real_world_size_u;
@ -199,6 +208,7 @@ public:
string _comment;
int _file_version;
GeospecificControlPoints _geospecific_control_points;
SubtextureDefs _subtexture_defs;
protected:
virtual bool extract_record(FltRecordReader &reader);

View File

@ -61,7 +61,7 @@ extract_record(FltRecordReader &reader) {
}
}
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -166,7 +166,7 @@ extract_record(FltRecordReader &reader) {
recompute_matrix();
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -117,7 +117,7 @@ extract_record(FltRecordReader &reader) {
recompute_matrix();
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -116,7 +116,7 @@ extract_record(FltRecordReader &reader) {
recompute_matrix();
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -187,7 +187,7 @@ extract_record(FltRecordReader &reader) {
recompute_matrix();
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -96,7 +96,7 @@ extract_record(FltRecordReader &reader) {
recompute_matrix();
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -95,7 +95,7 @@ extract_record(FltRecordReader &reader) {
recompute_matrix();
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -179,7 +179,7 @@ extract_record(FltRecordReader &reader) {
iterator.skip_bytes(4);
}
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -98,7 +98,7 @@ extract_record(FltRecordReader &reader) {
_vertices.push_back(_header->get_vertex_by_offset(vertex_offset));
}
nassertr(iterator.get_remaining_size() == 0, true);
check_remaining_size(iterator);
return true;
}

View File

@ -48,8 +48,8 @@ main(int argc, char *argv[]) {
header->set_texture_path(texture_path);
FltError result = header->read_flt(filename);
cerr << "Read result is " << result << "\n\n";
cerr << "Version is " << header->get_flt_version() << "\n";
cerr << "Read result is " << result << "\n"
<< "Version is " << header->get_flt_version() << "\n";
header->check_version();
if (result == FE_ok) {