Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/CParticle.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: 8440 byte(s)


1 #include "stdafx.h"
2 #include "CModelPlugin.h"
3 #include "CEnvPlugin.h"
4 #include "CScene.h"
5 #include "CConfigMode.h"
6
7 // 内部グローバル
8 VEC3 g_WindDir = V3ZERO; // 風方向
9 VEC3 g_WindDirNorm = V3DIR; // 風方向 (正規化済)
10
11 /*
12 * コンストラクタ
13 */
14 CParticleInst::CParticleInst(
15 CParticle *emitter, // エミッタ
16 VEC3 pos, // 座標
17 VEC3 dir, // 速度
18 float initradius, // 半径
19 float finradius, // アルファ
20 int lifetime, // 寿命
21 CScene *scene // シーン
22 ){
23 m_Emitter = emitter;
24 m_Pos = pos;
25 m_Dir = dir;
26 m_InitRadius = initradius;
27 m_FinRadius = finradius;
28 m_Alpha = 0.0f;
29 m_Angle = FRand(2.0f*D3DX_PI);
30 m_Color = MixColor(m_Emitter->m_Color[0], m_Emitter->m_Color[1], FRand(1.0f));
31 m_Lifetime = lifetime;
32 if(m_Lifetime<=0) m_Lifetime = 1;
33 m_Timer = 0;
34 m_Scene = scene;
35 }
36
37 /*
38 * レンダリング
39 */
40 void CParticleInst::Render(){
41 if(m_Timer>m_Lifetime || m_Scene!=g_Scene) return;
42 devTransBillboard(m_Pos);
43 devSetTexture(0, m_Emitter->m_Texture);
44 float radius = 1.41421356f*(m_Alpha*m_InitRadius+(1.0f-m_Alpha)*m_FinRadius);
45 float si = sinf(m_Angle)*radius, co = cosf(m_Angle)*radius;
46 D3DCOLOR col = ScaleColor(m_Color, m_Alpha);
47 if(m_Emitter->m_BlendMode){
48 devBLEND_ADD2();
49 }else{
50 devBLEND_ALPHA();
51 col = MultiplyColor(g_NoLightColor, col);
52 }
53 SetUVMap(0.0f, 0.0f, 1.0f, 1.0f);
54 TexMap3DRect(
55 VEC3(co, si, 0.0f), VEC3(si, -co, 0.0f),
56 VEC3(-co, -si, 0.0f), VEC3(-si, co, 0.0f), col);
57 }
58
59 /*
60 * シミュレーション進行
61 */
62 bool CParticleInst::Simulate(){
63 m_Timer++;
64 if(m_Timer>m_Lifetime) return false;
65 VEC3 wind = g_ConfigMode->GetWind() ? g_WindDir : V3ZERO;
66 m_Alpha = (float)(m_Lifetime-m_Timer)/m_Lifetime;
67 m_Pos += m_Dir;
68 m_Dir.y -= m_Emitter->m_Gravity;
69 m_Dir = (1.0f-m_Emitter->m_AirResistance)*m_Dir
70 +m_Emitter->m_AirResistance*(wind+V3RandS(m_Emitter->m_Turbulence));
71 return true;
72 }
73
74 ////////////////////////////////////////////////////////////////////////////////
75 ////////////////////////////////////////////////////////////////////////////////
76
77 /*
78 * 読込
79 */
80 char *CParticleState::Read(
81 char *str // 対象文字列
82 ){
83 char *eee;
84 if(!(str = Assignment(eee = str, "ParticleState"))) return NULL;
85 if(!(str = ConstFloat(eee = str, &m_EmissionCredit))) throw CSynErr(eee);
86 if(!(str = Character2(eee = str, ','))) throw CSynErr(eee);
87 if(!(str = Vector3D(eee = str, &m_OldPos))) throw CSynErr(eee);
88 if(!(str = Character2(eee = str, ';'))) throw CSynErr(eee);
89 return str;
90 }
91
92 /*
93 * 保存
94 */
95 void CParticleState::Save(
96 FILE *df, // ファイル
97 char *ind // インデント
98 ){
99 fprintf(df, "%sParticleState = %f, ", ind, m_EmissionCredit);
100 V3Save(df, m_OldPos, ";\n");
101 }
102
103 ////////////////////////////////////////////////////////////////////////////////
104 ////////////////////////////////////////////////////////////////////////////////
105
106 // 内部グローバル
107 list<CParticleInst> CParticle::ms_RenderList;
108
109 /*
110 * [static]
111 * リスト初期化
112 */
113 void CParticle::InitRenderList(){
114 ms_RenderList.clear();
115 }
116
117 /*
118 * [static]
119 * 全てレンダリング
120 */
121 void CParticle::RenderAll(){
122 if(!g_ConfigMode->GetMiscParticle()) return;
123 devResetMaterial();
124 //devSetZRead(FALSE);
125 devSetZWrite(FALSE);
126 devSetLighting(FALSE);
127 IParticleInst ipi;
128 for(ipi = ms_RenderList.begin(); ipi!=ms_RenderList.end(); ipi++) ipi->CalcDist();
129 ms_RenderList.sort();
130 for(ipi = ms_RenderList.begin(); ipi!=ms_RenderList.end(); ipi++) ipi->Render();
131 //devSetZRead(TRUE);
132 devSetZWrite(TRUE);
133 devSetLighting(TRUE);
134 devBLEND_ALPHA();
135 }
136
137 /*
138 * [static]
139 * 全てシミュレート
140 */
141 void CParticle::SimulateAll(){
142 IParticleInst ipi = ms_RenderList.begin();
143 // Dialog("particles %d", ms_RenderList.size());
144 while(ipi!=ms_RenderList.end()){
145 if(ipi->Simulate()) ipi++;
146 else ipi = ms_RenderList.erase(ipi);
147 }
148 }
149
150 /*
151 * 読込
152 */
153 char *CParticle::Read(
154 char *str, // 対象文字列
155 CModelPlugin *mpi // 車輌プラグイン
156 ){
157 char *tmp, *eee;
158 int i;
159 string obj, blend;
160 m_Texture = NULL;
161 if(!(str = BeginBlock(str, "Particle"))) return NULL;
162 if(!(str = AsgnString(eee = str, "TextureFileName", &m_TextureFileName))) throw CSynErr(eee);
163 if(!(str = AsgnString(eee = str, "AttachObject", &obj))) throw CSynErr(eee);
164 if(!(m_Link = mpi->FindObject(obj)))
165 throw CSynErr(eee, "%s: \"%s\"", lang(UndefinedObject), obj.c_str());
166 if(!(str = AsgnVector3D(eee = str, "SourceCoord", &m_SourceCoord))) throw CSynErr(eee);
167 if(!(str = AsgnFloat(eee = str, "MinQty", &m_MinQty))) throw CSynErr(eee);
168 if(tmp = AsgnFloat(eee = str, "MaxQty", &m_MaxQty)) str = tmp;
169 else m_MaxQty = m_MinQty;
170 if(tmp = AsgnFloat(eee = str, "VelocityRel", &m_VelocityRel)) str = tmp;
171 else m_VelocityRel = 0.0f;
172 if(tmp = AsgnFloat(eee = str, "AccelerationRel", &m_AccelerationRel)) str = tmp;
173 else m_AccelerationRel = 0.0f;
174 if(tmp = AsgnFloat(eee = str, "DecelerationRel", &m_DecelerationRel)) str = tmp;
175 else m_DecelerationRel = 0.0f;
176 m_MinQty /= MAXFPS;
177 m_MaxQty /= MAXFPS;
178 m_VelocityRel *= 3.6f;
179 m_AccelerationRel *= 3.6f*MAXFPS;
180 m_DecelerationRel *= 3.6f*MAXFPS;
181 if(!(str = AsgnFloat(eee = str, "Lifetime", m_Lifetime, 2, true))) throw CSynErr(eee);
182 if(!(str = AsgnVector3D(eee = str, "Direction", m_Direction, 2, true))) throw CSynErr(eee);
183 for(i = 0; i<2; i++) m_Direction[i] /= MAXFPS;
184 if(!(str = AsgnFloat(eee = str, "InitialRadius", m_InitialRadius, 2, true))) throw CSynErr(eee);
185 if(!(str = AsgnFloat(eee = str, "FinalRadius", m_FinalRadius, 2, true))) throw CSynErr(eee);
186 if(!(str = AsgnColor(eee = str, "Color", m_Color, 2, true))) throw CSynErr(eee);
187 if(!(str = AsgnIdentifier(eee = str, "BlendMode", &blend))) throw CSynErr(eee);
188 if(blend=="Alpha") m_BlendMode = 0;
189 else if(blend=="Add") m_BlendMode = 1;
190 else throw CSynErr(eee, "%s: \"%s\"", lang(InvalidBlendMode), blend.c_str());
191 if(tmp = AsgnFloat(eee = str, "AirResistance", &m_AirResistance)) str = tmp;
192 else m_AirResistance = 0.0f;
193 ValueArea(&m_AirResistance, 0.0f, 1.0f);
194 m_AirResistance = 1.0f-powf(1.0f-m_AirResistance, 1.0f/MAXFPS);
195 if(tmp = AsgnFloat(eee = str, "Gravity", &m_Gravity)) str = tmp;
196 else m_Gravity = 0.0f;
197 m_Gravity /= MAXFPS;
198 if(tmp = AsgnFloat(eee = str, "Turbulence", &m_Turbulence)) str = tmp;
199 else m_Turbulence = 0.0f;
200 m_Turbulence /= MAXFPS;
201 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
202 m_LinkState = NULL;
203 return str;
204 }
205
206 /*
207 * データ読込
208 */
209 void CParticle::LoadData(){
210 m_Texture = g_TexList.Get(FALSE, m_TextureFileName.c_str(), 0, !g_NamedObjectMipMap);
211 }
212
213 /*
214 * 状態変数をアタッチ
215 */
216 void CParticle::Link(
217 CParticleState *stt // 状態変数
218 ){
219 m_LinkState = stt;
220 m_LinkState->m_ApplyFlag = false;
221 }
222
223 /*
224 * レンダリングリストに登録
225 */
226 void CParticle::Register(
227 CScene *scene // シーン
228 ){
229 if(!m_LinkState || !scene) return;
230 m_LinkState->m_ApplyFlag = true;
231 CObject *obj = m_Link->GetObject();
232 VEC3 oright = obj->GetRight(), oup = obj->GetUp(), odir = obj->GetDir();
233 V3Norm(&oright, &oright);
234 V3Norm(&oup, &oup);
235 V3Norm(&odir, &odir);
236 VEC3 pos = obj->GetPos()+V3LocalToWorld(&m_SourceCoord, &oright, &oup, &odir);
237 if(m_LinkState->m_EmissionCredit<0.0f){
238 m_LinkState->m_EmissionCredit = 0.0f;
239 m_LinkState->m_EmissionCredit = 0.0f;
240 m_LinkState->m_OldPos = pos;
241 return;
242 }
243 VEC3 wind = g_ConfigMode->GetWind() ? g_WindDir : V3ZERO;
244 VEC3 delta = pos-m_LinkState->m_OldPos;
245 float speed = V3Len(&delta);
246 if(m_LinkState->m_OldSpeed<0.0f) m_LinkState->m_OldSpeed = speed;
247 float acc = speed-m_LinkState->m_OldSpeed;
248 float qty = m_MinQty+m_VelocityRel*speed
249 +(acc<0.0f ? -m_DecelerationRel : m_AccelerationRel)*acc;
250 ValueArea(&qty, m_MinQty, m_MaxQty);
251 m_LinkState->m_EmissionCredit += qty;
252 int i = 0, credit = (int)m_LinkState->m_EmissionCredit;
253 while(m_LinkState->m_EmissionCredit>=1.0f){
254 m_LinkState->m_EmissionCredit -= 1.0f;
255 VEC3 rad = V3Rand2(m_Direction[0], m_Direction[1]);
256 VEC3 dir = V3LocalToWorld(&rad, &oright, &oup, &odir)+delta;
257 float fix = (float)(i++)/credit, vfix = powf(1.0f-m_AirResistance, fix);
258 ms_RenderList.push_back(CParticleInst(
259 this, pos+fix*rad, vfix*dir+(1.0f-vfix)*wind,
260 FRand2(m_InitialRadius[0], m_InitialRadius[1]),
261 FRand2(m_FinalRadius[0], m_FinalRadius[1]),
262 Round(FRand2(m_Lifetime[0], m_Lifetime[1])*MAXFPS), scene));
263 }
264 m_LinkState->m_OldPos = pos;
265 m_LinkState->m_OldSpeed = speed;
266 }

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