Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/CPier.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations) (download) (as text)
Sun Aug 15 01:53:13 2010 UTC (13 years, 9 months ago) by okadu
File MIME type: text/x-c++src
File size: 8436 byte(s)


1 #include "stdafx.h"
2 #include "CScene.h"
3 #include "CPier.h"
4 #include "CPierPlugin.h"
5 #include "CSurfacePlugin.h"
6
7 // 外部定数
8 extern const float RAIL_SEG_MAX;
9
10 // 内部定数
11 extern const float TAPER_DIV_RATIO = 0.2f; // テーパ分割係数
12
13 // 外部グローバル
14 extern bool g_ShowPierSelect;
15 extern MAT8 g_MatSelect[];
16 extern MAT8 g_MatSelectA[];
17
18 // static メンバ
19 CPier **CPier::ms_Root = NULL;
20 float CPier::ms_MinDist;
21 CPier *CPier::ms_Detect;
22
23 /*
24 * コンストラクタ
25 */
26 CPier::CPier(){
27 m_Selected = 0;
28 m_Valid = true;
29 m_Next = NULL;
30 m_PierPlugin = NULL;
31 m_Next = NULL;
32 }
33
34 /*
35 * コンストラクタ
36 */
37 CPier::CPier(
38 VEC3 jpos, // ジョイント部座標
39 VEC3 jdir, // ジョイント部 right
40 VEC3 jup, // ジョイント部 up
41 float pickalt, // 地形 pick 開始高度
42 CPierPlugin *ipi // レールプラグイン
43 ){
44 m_Selected = 0;
45 m_Valid = false;
46 m_Next = NULL;
47 m_PierPlugin = ipi;
48 SetMesh();
49 m_JointObject.SetPos(jpos);
50 m_JointObject.SetDir(jdir, jup);
51 if(!Init(&pickalt)) return;
52 m_Valid = true;
53 m_Next = *ms_Root;
54 *ms_Root = this;
55 }
56
57 /*
58 * デストラクタ
59 */
60 CPier::~CPier(){
61 DELETE_V(m_Next);
62 }
63
64 /*
65 * メッシュ設定
66 */
67 void CPier::SetMesh(){
68 if(m_PierPlugin){
69 m_JointObject.SetMesh(m_PierPlugin->m_JointMesh, V3ZERO, m_PierPlugin->m_JointScale);
70 m_HeadObject.SetMesh(m_PierPlugin->m_HeadMesh, V3ZERO, m_PierPlugin->m_HeadScale);
71 m_BaseObject.SetMesh(m_PierPlugin->m_BaseMesh, V3ZERO, m_PierPlugin->m_BaseScale);
72 }
73 }
74
75 /*
76 * パーツ初期化
77 */
78 bool CPier::Init(
79 float *pickalt // 地形検出
80 ){
81 VEC3 jpos = m_JointObject.GetPos();
82 VEC3 jright, jup = m_JointObject.GetUp(), jdir = m_JointObject.GetDir();
83 V3NormAxis(&jright, &jup, &jdir);
84 VEC3 hpos = jpos+V3LocalToWorld(
85 &m_PierPlugin->m_JointToHeadLocal, &jright, &jup, &jdir);
86 VEC3 hright, hup = V3UP, hdir = VEC3(jdir.x, 0.0f, jdir.z);
87 V3NormAxis(&hright, &hup, &hdir);
88 m_HeadObject.SetPos(hpos);
89 m_HeadObject.SetDir(hdir, hup);
90 VEC3 top = hpos+V3LocalToWorld(
91 &m_PierPlugin->m_HeadToPierLocal, &hright, &hup, &hdir);
92 if(pickalt){
93 if(!g_Scene->PickScene(
94 VEC3(top.x, *pickalt, top.z), -V3UP, &m_SurfaceHit)) return false;
95 if(jpos.y-m_SurfaceHit.y<m_PierPlugin->m_BuildMinAlt) return false;
96 }else{
97 m_SurfaceHit = VEC3(top.x, m_SurfaceAlt, top.z);
98 }
99 m_SurfaceAlt = m_SurfaceHit.y;
100 VEC3 bottom = m_SurfaceHit+m_PierPlugin->m_BaseToPierLocal.y*V3UP;
101 m_PierArea = top.y-bottom.y;
102 m_PierUp = hdir;
103 if(m_PierPlugin->m_Direction){
104 m_PierBegin = bottom;
105 m_PierEnd = top;
106 m_PierRight = -hright;
107 m_PierDir = V3UP;
108 }else{
109 m_PierBegin = top;
110 m_PierEnd = bottom;
111 m_PierRight = hright;
112 m_PierDir = -V3UP;
113 }
114 m_BaseObject.SetPos(m_SurfaceHit+hright*m_PierPlugin->m_BaseToPierLocal.x
115 +hdir*m_PierPlugin->m_BaseToPierLocal.z);
116 m_BaseObject.SetDir(hdir, hup);
117 return true;
118 }
119
120 /*
121 * リストから削除
122 */
123 void CPier::Delete(){
124 g_Scene->DeletePierLink(this);
125 m_Next = NULL;
126 delete this;
127 }
128
129 /*
130 * 有効確認
131 *
132 * !m_Valid ならばリストは連結されていないので、メモリリーク等は発生しない
133 */
134 bool CPier::Confirm(){
135 if(m_Valid) return true;
136 delete this;
137 return false;
138 }
139
140 /*
141 * 入力チェック
142 */
143 void CPier::ScanInput(
144 int mode, // モード
145 VEC3 &rect1, // 領域始点
146 VEC3 &rect2 // 領域終点
147 ){
148 VEC3 center = 0.5f*(m_PierBegin+m_PierEnd);
149 VEC3 sc = WorldToScreen(center);
150 if(sc.z<0.0f) return;
151 switch(mode){
152 case 2:
153 if(rect1.x<=sc.x && sc.x<=rect2.x && rect1.y<=sc.y && sc.y<=rect2.y)
154 m_Selected |= 1;
155 else m_Selected &= 2;
156 break;
157 case 3:
158 if(CheckCtrl()){
159 m_Selected &= ~m_Selected<<1;
160 }else{
161 if(CheckShift()) m_Selected |= m_Selected<<1;
162 else m_Selected = m_Selected<<1;
163 }
164 m_Selected &= 2;
165 break;
166 case 4:
167 float dist = V3Len(&(rect1-sc));
168 float th = 250.0f*V3Len(&(m_PierBegin-m_PierEnd))
169 /(V3Len(&(GetVPos()-center))*g_FovRatio);
170 if(th<DETECT_2D_MIN) th = DETECT_2D_MIN;
171 if(dist<th && (ms_MinDist<0.0f || ms_MinDist>dist)){
172 ms_MinDist = dist;
173 ms_Detect = this;
174 }
175 m_Selected &= 2;
176 break;
177 }
178 }
179
180 /*
181 * 断面をダンプ
182 */
183 void CPier::Dump(
184 int prev // プレビューフラグ
185 ){
186 if(!m_PierPlugin || m_PierArea<=0.0f) return;
187 float tsx = 1.0f+m_PierArea*m_PierPlugin->m_TaperX;
188 float tsy = 1.0f+m_PierArea*m_PierPlugin->m_TaperY;
189 m_PierPlugin->ResetMapTemp();
190 int i, div = 1+Round(((tsx>tsy ? tsx : tsy)-1.0f)/TAPER_DIV_RATIO);
191 int smax = Round(2.0f*m_PierArea/RAIL_SEG_MAX);
192 if(div<smax) div = smax;
193 VEC3 tr1, tu1, tr2, tu2;
194 if(m_PierPlugin->m_Direction){
195 tr1 = m_PierRight*tsx; tu1 = m_PierUp*tsy;
196 tr2 = m_PierRight; tu2 = m_PierUp;
197 }else{
198 tr1 = m_PierRight; tu1 = m_PierUp;
199 tr2 = m_PierRight*tsx; tu2 = m_PierUp*tsy;
200 }
201 float divarea = m_PierArea/div;
202 for(i = 0; i<div; i++){
203 float q12 = (float)i/div, q11 = 1.0f-q12;
204 float q22 = (float)(i+1)/div, q21 = 1.0f-q22;
205 VEC3 p1 = q11*m_PierBegin+q12*m_PierEnd, r1 = q11*tr1+q12*tr2, u1 = q11*tu1+q12*tu2;
206 VEC3 p2 = q21*m_PierBegin+q22*m_PierEnd, r2 = q21*tr1+q22*tr2, u2 = q21*tu1+q22*tu2;
207 m_PierPlugin->Dump(p1, r1, u1, p1, r1, u1, p2, r2, u2, p2, r2, u2, divarea, prev);
208 }
209 }
210
211 /*
212 * 等間隔オブジェクトをレンダリング
213 */
214 void CPier::Render(){
215 if(!m_PierPlugin) return;
216 MAT8 *altmat = m_Selected ? &g_MatSelect[m_Selected] : NULL;
217 if(m_JointObject.IsMeshValid()){
218 if(g_ShowPierSelect && m_Selected) m_JointObject.RenderSC(altmat);
219 else m_JointObject.Render();
220 CastShadow(&m_JointObject);
221 }
222 if(m_PierPlugin->m_HeadObject.IsMeshValid()){
223 if(g_ShowPierSelect && m_Selected) m_HeadObject.RenderSC(altmat);
224 else m_HeadObject.Render();
225 CastShadow(&m_HeadObject);
226 }
227 float tsx, tsy;
228 if(m_PierArea<=0.0f){
229 tsx = tsy = 1.0f;
230 }else{
231 tsx = 1.0f+m_PierArea*m_PierPlugin->m_TaperX;
232 tsy = 1.0f+m_PierArea*m_PierPlugin->m_TaperY;
233 }
234 if(m_PierPlugin->m_BaseObject.IsMeshValid()){
235 if(g_ShowPierSelect && m_Selected) m_BaseObject.RenderSC(altmat);
236 else m_BaseObject.Render();
237 CastShadow(&m_BaseObject);
238 }
239 if(!g_ShowPierSelect && !g_ShadowNeeded
240 && (m_PierArea<=0.0f || !m_PierPlugin->HasInterval())) return;
241 m_PierPlugin->ResetMapTemp();
242 if(g_ShowPierSelect && m_Selected){
243 devSetTexture(0, NULL);
244 devSetMaterial(altmat);
245 devResetMatrix();
246 Dump(1);
247 }
248 if(m_PierPlugin->m_Direction) m_PierPlugin->Render(
249 m_PierBegin, R2L(m_PierRight*tsx), R2L(m_PierUp*tsy), m_PierDir,
250 m_PierBegin, R2L(m_PierRight*tsx), m_PierUp,
251 m_PierEnd, m_PierRight, m_PierUp, m_PierDir,
252 m_PierEnd, m_PierRight, m_PierUp, 3, m_PierArea, altmat);
253 else m_PierPlugin->Render(
254 m_PierBegin, m_PierRight, m_PierUp, m_PierDir,
255 m_PierBegin, m_PierRight, m_PierUp,
256 m_PierEnd, R2L(m_PierRight*tsx), R2L(m_PierUp*tsy), m_PierDir,
257 m_PierEnd, m_PierRight, m_PierUp, 3, m_PierArea, altmat);
258 }
259
260 /*
261 * 読込
262 */
263 char *CPier::Read(
264 char *str // 対象文字列
265 ){
266 char *eee;
267 if(!(str = BeginBlock(str, "Pier"))){
268 delete this;
269 return NULL;
270 }
271 void *oldadr;
272 if(!(str = AsgnPointer(eee = str, "Address", &oldadr))) throw CSynErr(eee);
273 g_AddressMap[oldadr] = this;
274 string pid;
275 if(!(str = AsgnString(eee = str, "PierPlugin", &pid))) throw CSynErr(eee);
276 m_PierPlugin = g_PierPluginList->FindPlugin(pid.c_str(), true);
277 VEC3 jpos, jdir, jup;
278 if(!(str = AsgnVector3D(eee = str, "JointPos", &jpos))) throw CSynErr(eee);
279 if(!(str = AsgnVector3D(eee = str, "JointDir", &jdir))) throw CSynErr(eee);
280 if(!(str = AsgnVector3D(eee = str, "JointUp", &jup))) throw CSynErr(eee);
281 if(!(str = AsgnFloat(eee = str, "SurfaceAlt", &m_SurfaceAlt))) throw CSynErr(eee);
282 SetMesh();
283 m_JointObject.SetPos(jpos);
284 m_JointObject.SetDir(jdir, jup);
285 if(m_PierPlugin) Init(NULL);
286 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
287 *ms_Root = this;
288 ms_Root = &m_Next;
289 return str;
290 }
291
292 /*
293 * 保存
294 */
295 void CPier::Save(
296 FILE *df // ファイル
297 ){
298 fprintf(df, "\t\t\tPier{\n");
299 fprintf(df, "\t\t\t\tAddress = %p;\n", this);
300 fprintf(df, "\t\t\t\tPierPlugin = \"%s\";\n", CheckPluginID(m_PierPlugin));
301 fprintf(df, "\t\t\t\tJointPos = "); V3Save(df, R2L(m_JointObject.GetPos()), ";\n");
302 fprintf(df, "\t\t\t\tJointDir = "); V3Save(df, R2L(m_JointObject.GetDir()), ";\n");
303 fprintf(df, "\t\t\t\tJointUp = "); V3Save(df, R2L(m_JointObject.GetUp()), ";\n");
304 fprintf(df, "\t\t\t\tSurfaceAlt = %f;\n", m_SurfaceAlt);
305 fprintf(df, "\t\t\t}\n");
306 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26