1 /*******************************************************
2 Lightwave Object Loader for OSG
3
4 Copyright (C) 2004 Marco Jez <marco.jez@poste.it>
5 OpenSceneGraph is (C) 2004 Robert Osfield
6 ********************************************************/
7
8 #include "Block.h"
9
10 #include <osg/Notify>
11 #include <osg/Matrix>
12
13 using namespace lwosg;
14
Block(const lwo2::FORM::SURF::BLOK * blok)15 Block::Block(const lwo2::FORM::SURF::BLOK *blok)
16 : enabled_(true),
17 opacity_type_(ADDITIVE),
18 opacity_amount_(1),
19 displacement_axis_(X)
20 {
21 if (blok) {
22 compile(blok);
23 }
24 }
25
read_common_attributes(const iff::Chunk_list & subchunks)26 void Block::read_common_attributes(const iff::Chunk_list &subchunks)
27 {
28 for (iff::Chunk_list::const_iterator i=subchunks.begin(); i!=subchunks.end(); ++i) {
29 const lwo2::FORM::SURF::BLOK::CHAN *chan = dynamic_cast<const lwo2::FORM::SURF::BLOK::CHAN *>(*i);
30 if (chan) {
31 channel_ = std::string(chan->texture_channel.id, 4);
32 }
33 const lwo2::FORM::SURF::BLOK::ENAB *enab = dynamic_cast<const lwo2::FORM::SURF::BLOK::ENAB *>(*i);
34 if (enab) {
35 enabled_ = enab->enable != 0;
36 }
37 const lwo2::FORM::SURF::BLOK::OPAC *opac = dynamic_cast<const lwo2::FORM::SURF::BLOK::OPAC *>(*i);
38 if (opac) {
39 opacity_type_ = static_cast<Opacity_type>(opac->type);
40 opacity_amount_ = opac->opacity.fraction;
41 }
42 const lwo2::FORM::SURF::BLOK::AXIS *axis = dynamic_cast<const lwo2::FORM::SURF::BLOK::AXIS *>(*i);
43 if (axis) {
44 displacement_axis_ = static_cast<Axis_type>(axis->displacement_axis);
45 }
46 }
47 }
48
compile(const lwo2::FORM::SURF::BLOK * blok)49 void Block::compile(const lwo2::FORM::SURF::BLOK *blok)
50 {
51 const lwo2::FORM::SURF::BLOK::IMAP *imap = dynamic_cast<const lwo2::FORM::SURF::BLOK::IMAP *>(blok->header);
52 if (imap) {
53 type_ = "IMAP";
54 ordinal_ = imap->ordinal;
55
56 // read common parameters
57 read_common_attributes(imap->block_attributes);
58
59 // read imagemap-related attributes
60 for (iff::Chunk_list::const_iterator bi=blok->attributes.begin(); bi!=blok->attributes.end(); ++bi) {
61 const lwo2::FORM::SURF::BLOK::IMAP::TMAP *tmap = dynamic_cast<const lwo2::FORM::SURF::BLOK::IMAP::TMAP *>(*bi);
62 if (tmap) {
63 Texture_mapping mapping;
64 for (iff::Chunk_list::const_iterator i=tmap->attributes.begin(); i!=tmap->attributes.end(); ++i) {
65 const lwo2::FORM::SURF::BLOK::IMAP::TMAP::CNTR *cntr = dynamic_cast<const lwo2::FORM::SURF::BLOK::IMAP::TMAP::CNTR *>(*i);
66 if (cntr) {
67 mapping.center_ = osg::Vec3(cntr->vector.X, cntr->vector.Y, cntr->vector.Z);
68 }
69 const lwo2::FORM::SURF::BLOK::IMAP::TMAP::SIZE *size = dynamic_cast<const lwo2::FORM::SURF::BLOK::IMAP::TMAP::SIZE *>(*i);
70 if (size) {
71 mapping.size_ = osg::Vec3(size->vector.X, size->vector.Y, size->vector.Z);
72 }
73 const lwo2::FORM::SURF::BLOK::IMAP::TMAP::ROTA *rota = dynamic_cast<const lwo2::FORM::SURF::BLOK::IMAP::TMAP::ROTA *>(*i);
74 if (rota) {
75 mapping.rotation_ = osg::Vec3(rota->vector.X, rota->vector.Y, rota->vector.Z);
76 }
77 const lwo2::FORM::SURF::BLOK::IMAP::TMAP::CSYS *csys = dynamic_cast<const lwo2::FORM::SURF::BLOK::IMAP::TMAP::CSYS *>(*i);
78 if (csys) {
79 mapping.csys_ = static_cast<Texture_mapping::Coordinate_system_type>(csys->type);
80 }
81 }
82 imap_.mapping = mapping;
83 }
84
85 const lwo2::FORM::SURF::BLOK::IMAP::PROJ *proj = dynamic_cast<const lwo2::FORM::SURF::BLOK::IMAP::PROJ *>(*bi);
86 if (proj) {
87 imap_.projection = static_cast<Image_map::Projection_mode>(proj->projection_mode);
88 }
89
90 const lwo2::FORM::SURF::BLOK::IMAP::AXIS *axis = dynamic_cast<const lwo2::FORM::SURF::BLOK::IMAP::AXIS *>(*bi);
91 if (axis) {
92 imap_.axis = static_cast<Image_map::Axis_type>(axis->texture_axis);
93 }
94
95 const lwo2::FORM::SURF::BLOK::IMAP::IMAG *imag = dynamic_cast<const lwo2::FORM::SURF::BLOK::IMAP::IMAG *>(*bi);
96 if (imag) {
97 imap_.image_map = imag->texture_image.index;
98 }
99
100 const lwo2::FORM::SURF::BLOK::IMAP::WRAP *wrap = dynamic_cast<const lwo2::FORM::SURF::BLOK::IMAP::WRAP *>(*bi);
101 if (wrap) {
102 imap_.width_wrap = static_cast<Image_map::Wrap_type>(wrap->width_wrap);
103 imap_.height_wrap = static_cast<Image_map::Wrap_type>(wrap->height_wrap);
104 }
105
106 const lwo2::FORM::SURF::BLOK::IMAP::WRPW *wrpw = dynamic_cast<const lwo2::FORM::SURF::BLOK::IMAP::WRPW *>(*bi);
107 if (wrpw) {
108 imap_.wrap_amount_w = wrpw->cycles.fraction;
109 }
110
111 const lwo2::FORM::SURF::BLOK::IMAP::WRPH *wrph = dynamic_cast<const lwo2::FORM::SURF::BLOK::IMAP::WRPH *>(*bi);
112 if (wrph) {
113 imap_.wrap_amount_h = wrph->cycles.fraction;
114 }
115
116 const lwo2::FORM::SURF::BLOK::IMAP::VMAP *vmap = dynamic_cast<const lwo2::FORM::SURF::BLOK::IMAP::VMAP *>(*bi);
117 if (vmap) {
118 imap_.uv_map = vmap->txuv_map_name;
119 }
120
121 const lwo2::FORM::SURF::BLOK::IMAP::TAMP *tamp = dynamic_cast<const lwo2::FORM::SURF::BLOK::IMAP::TAMP *>(*bi);
122 if (tamp) {
123 imap_.texture_amplitude = tamp->amplitude.fraction;
124 }
125 }
126
127 } else {
128 OSG_WARN << "Warning: lwosg::Block: only IMAP (image map) block types are supported, this block will be ignored" << std::endl;
129 }
130 }
131
setup_texture_point(const osg::Vec3 & P) const132 osg::Vec3 Block::setup_texture_point(const osg::Vec3 &P) const
133 {
134 osg::Vec3 Q = P;
135
136 const osg::Vec3 &ypr = imap_.mapping.rotation_;
137 Q -= imap_.mapping.center_;
138 Q = Q * osg::Matrix::rotate(ypr.z(), osg::Vec3(0, 0, -1));
139 Q = Q * osg::Matrix::rotate(ypr.x(), osg::Vec3(0, 1, 0));
140 Q = Q * osg::Matrix::rotate(ypr.y(), osg::Vec3(-1, 0, 0));
141 if (imap_.projection != Image_map::SPHERICAL) {
142 Q.x() *= 1/imap_.mapping.size_.x();
143 Q.y() *= 1/imap_.mapping.size_.y();
144 Q.z() *= 1/imap_.mapping.size_.z();
145 }
146
147 return Q;
148 }
149