forked from Rowland/EG
263 lines
7.4 KiB
C++
263 lines
7.4 KiB
C++
/**
|
|
* PANDA 3D SOFTWARE
|
|
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
*
|
|
* All use of this software is subject to the terms of the revised BSD
|
|
* license. You should have received a copy of this license along
|
|
* with this source code in a file named "LICENSE."
|
|
*
|
|
* @file fltGeometry.cxx
|
|
* @author drose
|
|
* @date 2001-02-28
|
|
*/
|
|
|
|
#include "fltGeometry.h"
|
|
#include "fltRecordReader.h"
|
|
#include "fltRecordWriter.h"
|
|
#include "fltHeader.h"
|
|
#include "fltMaterial.h"
|
|
|
|
TypeHandle FltGeometry::_type_handle;
|
|
|
|
/**
|
|
*
|
|
*/
|
|
FltGeometry::
|
|
FltGeometry(FltHeader *header) : FltBeadID(header) {
|
|
_ir_color = 0;
|
|
_relative_priority = 0;
|
|
_draw_type = DT_solid_cull_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 = F_no_color;
|
|
_light_mode = LM_face_no_normal;
|
|
_texture_mapping_index = 0;
|
|
_color_index = 0;
|
|
_alt_color_index = 0;
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the primary color of the face, as a four-component value (including
|
|
* alpha as the transparency channel).
|
|
*
|
|
* If has_color() is false, the result is white, but still reflects the
|
|
* transparency correctly.
|
|
*/
|
|
LColor FltGeometry::
|
|
get_color() const {
|
|
LColor color;
|
|
|
|
if (!has_color() || (_texwhite && has_texture())) {
|
|
// Force this one white.
|
|
color.set(1.0, 1.0, 1.0, 1.0);
|
|
|
|
} else if (has_material()) {
|
|
// If we have a material, that replaces the color.
|
|
FltMaterial *material = get_material();
|
|
color.set(material->_diffuse[0],
|
|
material->_diffuse[1],
|
|
material->_diffuse[2],
|
|
material->_alpha);
|
|
} else {
|
|
LRGBColor rgb =
|
|
_header->get_rgb(_color_index, (_flags & F_packed_color) != 0,
|
|
_packed_color);
|
|
color.set(rgb[0], rgb[1], rgb[2], 1.0);
|
|
}
|
|
|
|
// Modify the whole thing by our transparency.
|
|
PN_stdfloat alpha = 1.0 - (_transparency / 65535.0);
|
|
color[3] *= alpha;
|
|
|
|
return color;
|
|
}
|
|
|
|
/**
|
|
* Sets the primary color of the face, using the packed color convention.
|
|
*/
|
|
void FltGeometry::
|
|
set_color(const LColor &color) {
|
|
set_rgb(LRGBColor(color[0], color[1], color[2]));
|
|
_transparency = (int)floor((1.0 - color[3]) * 65535.0);
|
|
}
|
|
|
|
/**
|
|
* Returns the primary color of the face, as a three-component value ignoring
|
|
* transparency.
|
|
*/
|
|
LRGBColor FltGeometry::
|
|
get_rgb() const {
|
|
if (!has_color() || (_texwhite && has_texture())) {
|
|
// Force this one white.
|
|
return LRGBColor(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);
|
|
}
|
|
|
|
/**
|
|
* Sets the primary color of the face, using the packed color convention; does
|
|
* not affect transparency.
|
|
*/
|
|
void FltGeometry::
|
|
set_rgb(const LRGBColor &rgb) {
|
|
_packed_color.set_rgb(rgb);
|
|
_flags = ((_flags & ~F_no_color) | F_packed_color);
|
|
|
|
// If we have a color, we can't have a material.
|
|
_material_index = -1;
|
|
_texwhite = false;
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
/**
|
|
* If has_alt_color() indicates true, returns the alternate color of the face,
|
|
* as a four-component value (including alpha as the transparency channel).
|
|
*/
|
|
LColor FltGeometry::
|
|
get_alt_color() const {
|
|
nassertr(has_alt_color(), LColor(0.0, 0.0, 0.0, 0.0));
|
|
|
|
return _header->get_color(_alt_color_index, (_flags & F_packed_color) != 0,
|
|
_alt_packed_color, _transparency);
|
|
}
|
|
|
|
/**
|
|
* If has_alt_color() indicates true, returns the alternate color of the face,
|
|
* as a three-component value ignoring transparency.
|
|
*/
|
|
LRGBColor FltGeometry::
|
|
get_alt_rgb() const {
|
|
nassertr(has_alt_color(), LRGBColor(0.0, 0.0, 0.0));
|
|
|
|
return _header->get_rgb(_alt_color_index, (_flags & F_packed_color) != 0,
|
|
_alt_packed_color);
|
|
}
|
|
|
|
/**
|
|
* 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();
|
|
if (_header->get_flt_version() >= 1420) {
|
|
_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;
|
|
}
|
|
|
|
if (_header->get_flt_version() >= 1520) {
|
|
_texture_mapping_index = iterator.get_be_int16();
|
|
iterator.skip_bytes(2);
|
|
_color_index = iterator.get_be_int32();
|
|
_alt_color_index = iterator.get_be_int32();
|
|
iterator.skip_bytes(2 + 2);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
if (_header->get_flt_version() >= 1520) {
|
|
// New with 15.2
|
|
datagram.add_be_int16(_texture_mapping_index);
|
|
datagram.pad_bytes(2);
|
|
datagram.add_be_int32(_color_index);
|
|
datagram.add_be_int32(_alt_color_index);
|
|
datagram.pad_bytes(2 + 2);
|
|
}
|
|
|
|
return true;
|
|
}
|