use "%f" format for angles, prevents weird exponential stuff
[divverent/netradiant.git] / plugins / entity / scale.h
1 /*
2 Copyright (C) 2001-2006, William Joseph.
3 All Rights Reserved.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #if !defined(INCLUDED_SCALE_H)
23 #define INCLUDED_SCALE_H
24
25 #include "ientity.h"
26
27 #include "math/matrix.h"
28 #include "generic/callback.h"
29 #include "stringio.h"
30
31 const Vector3 SCALEKEY_IDENTITY = Vector3(1, 1, 1);
32
33 inline void default_scale(Vector3& scale)
34 {
35   scale = SCALEKEY_IDENTITY;
36 }
37 inline void read_scale(Vector3& scalevec, const char* value)
38 {
39   float scale;
40   if(!string_parse_float(value, scale)
41     || scale == 0)
42   {
43     default_scale(scalevec);
44   }
45   else
46   {
47     scalevec = Vector3(scale, scale, scale);
48   }
49 }
50 inline void read_scalevec(Vector3& scale, const char* value)
51 {
52   if(!string_parse_vector3(value, scale)
53     || scale[0] == 0
54     || scale[1] == 0
55     || scale[2] == 0)
56     default_scale(scale);
57 }
58 inline void write_scale(const Vector3& scale, Entity* entity)
59 {
60   if(scale[0] == 1 && scale[1] == 1 && scale[2] == 1)
61   {
62     entity->setKeyValue("modelscale", "");
63     entity->setKeyValue("modelscale_vec", "");
64   }
65   else
66   {
67     char value[64];
68
69     if(scale[0] == scale[1] && scale[0] == scale[2])
70     {
71       sprintf(value, "%f", scale[0]);
72       entity->setKeyValue("modelscale_vec", "");
73       entity->setKeyValue("modelscale", value);
74     }
75     else
76     {
77       sprintf(value, "%f %f %f", scale[0], scale[1], scale[2]);
78       entity->setKeyValue("modelscale", "");
79       entity->setKeyValue("modelscale_vec", value);
80     }
81   }
82 }
83
84 inline Vector3 scale_scaled(const Vector3& scale, const Vector3& scaling)
85 {
86   return matrix4_get_scale_vec3(
87     matrix4_multiplied_by_matrix4(
88       matrix4_scale_for_vec3(scale),
89       matrix4_scale_for_vec3(scaling)
90     )
91   );
92 }
93
94
95 class ScaleKey
96 {
97   Callback m_scaleChanged;
98 public:
99   Vector3 m_scale;
100
101
102   ScaleKey(const Callback& scaleChanged)
103     : m_scaleChanged(scaleChanged), m_scale(SCALEKEY_IDENTITY)
104   {
105   }
106
107   void uniformScaleChanged(const char* value)
108   {
109     read_scale(m_scale, value);
110     m_scaleChanged();
111   }
112   typedef MemberCaller1<ScaleKey, const char*, &ScaleKey::uniformScaleChanged> UniformScaleChangedCaller;
113
114   void scaleChanged(const char* value)
115   {
116     read_scalevec(m_scale, value);
117     m_scaleChanged();
118   }
119   typedef MemberCaller1<ScaleKey, const char*, &ScaleKey::scaleChanged> ScaleChangedCaller;
120
121   void write(Entity* entity) const
122   {
123     write_scale(m_scale, entity);
124   }
125 };
126
127
128 #endif