| 1 |
#include "stdafx.h" |
| 2 |
#include "CCamera.h" |
| 3 |
#include "CSaveFile.h" |
| 4 |
#include "CModelPlugin.h" |
| 5 |
#include "CEnvPlugin.h" |
| 6 |
#include "CEnvEditMode.h" |
| 7 |
#include "CSimulationMode.h" |
| 8 |
#include "CConfigMode.h" |
| 9 |
|
| 10 |
// 内部定数 |
| 11 |
const float AXIAL_INCLINATION = D3DXToRadian(23.44f); // 地軸の傾き |
| 12 |
const float DAYS_PER_YEAR = 365.2425f; // 年当たり平均日数 |
| 13 |
const float REV_PER_DAY = 2.0f*D3DX_PI/DAYS_PER_YEAR; // 1 日当たり公転角度 |
| 14 |
const float ROT_PER_DAY = 2.0f*D3DX_PI+REV_PER_DAY; // 1 日当たり自転角度 |
| 15 |
|
| 16 |
// 外部グローバル |
| 17 |
extern int g_AncientNightFlag; |
| 18 |
extern COffScreen g_HidefCapture; |
| 19 |
extern bool g_HidefCaptureFlag; |
| 20 |
|
| 21 |
// 内部グローバル |
| 22 |
float g_DayAlpha; |
| 23 |
float g_NightAlpha; |
| 24 |
D3DCOLOR g_NoLightColor; |
| 25 |
|
| 26 |
/* |
| 27 |
* 読込 |
| 28 |
*/ |
| 29 |
char *CLightSetting::Read( |
| 30 |
char *str // 対象文字列 |
| 31 |
){ |
| 32 |
char *eee; |
| 33 |
if(!(str = BeginBlock(str, "Set"))) return NULL; |
| 34 |
if(!(str = AsgnFloat(eee = str, "SunAlt", &m_SunAlt))) throw CSynErr(eee); |
| 35 |
if(!(str = AsgnColor(eee = str, "Directional", &m_Directional))) throw CSynErr(eee); |
| 36 |
if(!(str = AsgnColor(eee = str, "Ambient", &m_Ambient))) throw CSynErr(eee); |
| 37 |
if(!(str = AsgnColor(eee = str, "SkyColor", &m_SkyColor))) throw CSynErr(eee); |
| 38 |
if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK); |
| 39 |
return str; |
| 40 |
} |
| 41 |
|
| 42 |
//////////////////////////////////////////////////////////////////////////////// |
| 43 |
//////////////////////////////////////////////////////////////////////////////// |
| 44 |
|
| 45 |
/* |
| 46 |
* 読込 |
| 47 |
*/ |
| 48 |
char *CMoon::Read( |
| 49 |
char *str // 対象文字列 |
| 50 |
){ |
| 51 |
char *tmp, *eee; |
| 52 |
if(!(str = BeginBlock(str, "Moon"))) return NULL; |
| 53 |
if(!(str = AsgnString(eee = str, "ModelFileName", &m_MoonFile))) throw CSynErr(eee); |
| 54 |
if(tmp = AsgnFloat(str, "ModelScale", &m_MoonScale)) str = tmp; |
| 55 |
else m_MoonScale = 1.0f; |
| 56 |
if(!(str = AsgnFloat(eee = str, "AxialInclination", &m_AxialInclination))) throw CSynErr(eee); |
| 57 |
m_AxialInclination = D3DXToRadian(m_AxialInclination); |
| 58 |
if(!(str = AsgnFloat(eee = str, "RevolutionPeriod", &m_RevolutionPeriod))) throw CSynErr(eee); |
| 59 |
if(!(str = AsgnFloat(eee = str, "InitialPhase", &m_InitialPhase))) throw CSynErr(eee); |
| 60 |
m_RevolutionPerDay = 2.0f*D3DX_PI/m_RevolutionPeriod; |
| 61 |
if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK); |
| 62 |
return str; |
| 63 |
} |
| 64 |
|
| 65 |
/* |
| 66 |
* データ読込 |
| 67 |
*/ |
| 68 |
void CMoon::LoadData(){ |
| 69 |
m_MoonMesh = g_MeshList.Get(FALSE, (char *)m_MoonFile.c_str(), 0, 1); |
| 70 |
m_MoonObject.SetMesh(m_MoonMesh, V3ZERO, m_MoonScale); |
| 71 |
} |
| 72 |
|
| 73 |
/* |
| 74 |
* レンダリング |
| 75 |
*/ |
| 76 |
void CMoon::Render( |
| 77 |
double abstime, // 絶対時間 |
| 78 |
float latitude, // 緯度 |
| 79 |
VEC3 sdir, // 太陽の方向 |
| 80 |
float rot // 地球の自転角度 |
| 81 |
){ |
| 82 |
float rev = NormAngle((abstime+m_InitialPhase)*m_RevolutionPerDay); |
| 83 |
m_MoonObject.SetDir(-V3UP, V3DIR); |
| 84 |
m_MoonObject.RotX(m_AxialInclination-latitude); |
| 85 |
m_MoonObject.RotY(-rev); |
| 86 |
VEC3 rotaxis; |
| 87 |
V3Norm(&rotaxis, &V3WorldToLocal( |
| 88 |
&VEC3(0.0f, sin(latitude), cos(latitude)), &m_MoonObject)); |
| 89 |
m_MoonObject.RotAxis(rotaxis, rot); |
| 90 |
VEC3 mdir = m_MoonObject.GetDir(); |
| 91 |
V3Norm(&mdir, &mdir); |
| 92 |
m_MoonObject.SetPos(GetVPos()+10.0f*mdir); |
| 93 |
m_MoonObject.SetDir(-sdir, VEC3(sdir.y, sdir.z, sdir.x)); |
| 94 |
m_MoonObject.RenderAP(1.0); |
| 95 |
} |
| 96 |
|
| 97 |
//////////////////////////////////////////////////////////////////////////////// |
| 98 |
//////////////////////////////////////////////////////////////////////////////// |
| 99 |
|
| 100 |
/* |
| 101 |
* ロード |
| 102 |
*/ |
| 103 |
bool CEnvPlugin::Load(){ |
| 104 |
char *str = m_Script, *tmp, *eee; |
| 105 |
if(!ChDir() || !m_Script) return false; |
| 106 |
try{ |
| 107 |
if(!(str = BeginBlock(eee = str, "EnvInfo"))) throw CSynErr(eee); |
| 108 |
if(!(str = AsgnFloat(eee = str, "Latitude", &m_Latitude))) throw CSynErr(eee); |
| 109 |
if(!(str = AsgnString(eee = str, "EnvMapTexFileName", &m_EnvMapTexFile))) throw CSynErr(eee); |
| 110 |
if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK); |
| 111 |
m_Latitude = D3DXToRadian(m_Latitude); |
| 112 |
|
| 113 |
if(!(str = BeginBlock(eee = str, "Landscape"))) throw CSynErr(eee); |
| 114 |
if(!(str = AsgnString(eee = str, "ModelFileName", &m_LandscapeFile))) throw CSynErr(eee); |
| 115 |
if(tmp = AsgnFloat(eee = str, "ModelScale", &m_LandscapeScale)) str = tmp; |
| 116 |
else m_LandscapeScale = 1.0f; |
| 117 |
if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK); |
| 118 |
|
| 119 |
if(!(str = BeginBlock(eee = str, "Sun"))) throw CSynErr(eee); |
| 120 |
if(!(str = AsgnString(eee = str, "ModelFileName", &m_SunFile))) throw CSynErr(eee); |
| 121 |
if(tmp = AsgnFloat(str, "ModelScale", &m_SunScale)) str = tmp; |
| 122 |
else m_SunScale = 1.0f; |
| 123 |
if(!(str = AsgnFloat(eee = str, "AxialInclination", &m_SunAxialInclination))) throw CSynErr(eee); |
| 124 |
m_SunAxialInclination = D3DXToRadian(m_SunAxialInclination); |
| 125 |
if(tmp = m_SunLensFlare.Read(str)) str = tmp; |
| 126 |
if(tmp = m_SunWhiteout.Read(str)) str = tmp; |
| 127 |
|
| 128 |
if(!(str = BeginBlock(eee = str, "Lighting"))) throw CSynErr(eee); |
| 129 |
if(!(str = AsgnFloat(eee = str, "NightThreshold", &m_NightThreshold))) throw CSynErr(eee); |
| 130 |
if(!(str = AsgnColor(eee = str, "ShadowColor", &m_ShadowColor))) throw CSynErr(eee); |
| 131 |
m_Light.clear(); |
| 132 |
CLightSetting light; |
| 133 |
while(tmp = light.Read(str)){ |
| 134 |
str = tmp; |
| 135 |
m_Light.push_back(light); |
| 136 |
} |
| 137 |
m_Light.sort(); |
| 138 |
if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK); |
| 139 |
|
| 140 |
if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK); |
| 141 |
|
| 142 |
m_Moon.clear(); |
| 143 |
CMoon moon; |
| 144 |
while(tmp = moon.Read(str)){ |
| 145 |
str = tmp; |
| 146 |
m_Moon.push_back(moon); |
| 147 |
} |
| 148 |
|
| 149 |
if(*(eee = str)) throw CSynErr(eee); |
| 150 |
} |
| 151 |
catch(CSynErr err){ |
| 152 |
HandleError(&err); |
| 153 |
return false; |
| 154 |
} |
| 155 |
if(m_EnvMapTexFile.size()) |
| 156 |
m_EnvMapTexture = g_TexList.Get(FALSE, m_EnvMapTexFile.c_str()); |
| 157 |
else m_EnvMapTexture = NULL; |
| 158 |
m_LandscapeMesh = g_MeshList.Get(FALSE, (char *)m_LandscapeFile.c_str(), 0, 1); |
| 159 |
m_LandscapeObject.SetMesh(m_LandscapeMesh, V3ZERO, m_LandscapeScale); |
| 160 |
ChDir(); |
| 161 |
m_SunMesh = g_MeshList.Get(FALSE, (char *)m_SunFile.c_str(), 0, 1); |
| 162 |
m_SunObject.SetMesh(m_SunMesh, V3ZERO, m_SunScale); |
| 163 |
ChDir(); |
| 164 |
m_SunLensFlare.LoadData(); |
| 165 |
ChDir(); |
| 166 |
IMoon im = m_Moon.begin(); |
| 167 |
for(; im!=m_Moon.end(); im++){ |
| 168 |
im->LoadData(); |
| 169 |
ChDir(); |
| 170 |
} |
| 171 |
DELETE_A(m_Buffer); |
| 172 |
return true; |
| 173 |
} |
| 174 |
|
| 175 |
/* |
| 176 |
* プレビュー設定 |
| 177 |
*/ |
| 178 |
void CEnvPlugin::SetPreview(){ |
| 179 |
ms_PreviewState = true; |
| 180 |
g_Env = this; |
| 181 |
string desc = g_Env->GetBasicInfo(); |
| 182 |
desc += "\n"+g_Env->GetDescription(); |
| 183 |
g_EnvEditMode->SetProperty((char *)desc.c_str()); |
| 184 |
} |
| 185 |
|
| 186 |
/* |
| 187 |
* 環境描画 |
| 188 |
*/ |
| 189 |
void CEnvPlugin::Render( |
| 190 |
double abstime // 絶対時間 |
| 191 |
){ |
| 192 |
LoadAndGet(); |
| 193 |
if(abstime<0.0) abstime = g_SaveFile->GetAbsTime(); |
| 194 |
int rotmode = g_SimulationMode->GetEarthRevolution(); |
| 195 |
double rottime = abstime; |
| 196 |
if(rotmode){ |
| 197 |
abstime = 365*(rotmode%4)/4-10.0; |
| 198 |
rottime += abstime-(int)rottime; |
| 199 |
} |
| 200 |
// 冬至: 12/22 よって 1/1 から 10 日分ずらす |
| 201 |
float rev = NormAngle((abstime+10.0)*REV_PER_DAY); // 公転角度 |
| 202 |
m_SunObject.SetDir(-V3UP, V3DIR); |
| 203 |
m_SunObject.RotX(m_SunAxialInclination-m_Latitude); |
| 204 |
m_SunObject.RotY(-rev); |
| 205 |
VEC3 rotaxis; // 自転軸 |
| 206 |
float rot; // 自転角度 |
| 207 |
V3Norm(&rotaxis, &V3WorldToLocal( |
| 208 |
&VEC3(0.0f, sin(m_Latitude), cos(m_Latitude)), &m_SunObject)); |
| 209 |
switch(g_SimulationMode->GetEarthRotation()){ |
| 210 |
case 0: rot = NormAngle(rottime*ROT_PER_DAY); break; |
| 211 |
case 1: rot = rev+0.5f*ROT_PER_DAY; break; |
| 212 |
case 2: rot = rev; break; |
| 213 |
} |
| 214 |
m_SunObject.RotAxis(rotaxis, rot); |
| 215 |
VEC3 sdir = m_SunObject.GetDir(); |
| 216 |
V3Norm(&sdir, &sdir); |
| 217 |
g_DayAlpha = (sdir.y-m_NightThreshold)*10.0f; |
| 218 |
ValueArea(&g_DayAlpha, 0.0f, 1.0f); |
| 219 |
g_NightAlpha = 1.0f-g_DayAlpha; |
| 220 |
m_SunObject.SetPos(GetVPos()+10.0f*sdir); |
| 221 |
D3DCOLOR directional, ambient, skycolor; |
| 222 |
float sunalt = sdir.y; |
| 223 |
g_SystemSwitch[SYS_SW_NIGHT].SetValue(g_AncientNightFlag = sunalt<m_NightThreshold); |
| 224 |
if(m_Light.size()){ |
| 225 |
ILightSetting il1 = m_Light.begin(), il2 = il1; |
| 226 |
il2++; |
| 227 |
for(; il1!=m_Light.end(); il1 = il2, il2++){ |
| 228 |
if(sunalt<=il1->m_SunAlt || il2==m_Light.end()){ |
| 229 |
directional = il1->m_Directional; |
| 230 |
ambient = il1->m_Ambient; |
| 231 |
skycolor = il1->m_SkyColor; |
| 232 |
break; |
| 233 |
}else if(sunalt<=il2->m_SunAlt){ |
| 234 |
float p1 = (il2->m_SunAlt-sunalt)/(il2->m_SunAlt-il1->m_SunAlt); |
| 235 |
directional = MixColor(il1->m_Directional, il2->m_Directional, p1); |
| 236 |
ambient = MixColor(il1->m_Ambient, il2->m_Ambient, p1); |
| 237 |
skycolor = MixColor(il1->m_SkyColor, il2->m_SkyColor, p1); |
| 238 |
break; |
| 239 |
} |
| 240 |
} |
| 241 |
}else{ |
| 242 |
directional = 0xffffffff; |
| 243 |
ambient = 0xff808080; |
| 244 |
skycolor = 0xff000000; |
| 245 |
} |
| 246 |
SetDirLight(-sdir, ACtoCV(directional)); |
| 247 |
if(g_HidefCaptureFlag) g_HidefCapture.Begin(skycolor); |
| 248 |
else BeginScene(skycolor); |
| 249 |
devSetState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); |
| 250 |
devSetZRead(FALSE); |
| 251 |
devSetZWrite(FALSE); |
| 252 |
devSetLighting(FALSE); |
| 253 |
devBLEND_ADD2(); |
| 254 |
m_SunObject.RenderAP(1.0f); |
| 255 |
devSetAmbient(0xffffffff); |
| 256 |
IMoon im = m_Moon.begin(); |
| 257 |
for(; im!=m_Moon.end(); im++) im->Render(abstime, m_Latitude, sdir, rot); |
| 258 |
devSetLighting(TRUE); |
| 259 |
devBLEND_ALPHA(); |
| 260 |
devSetAmbient(g_NoLightColor = MaxColor(directional, ambient)); |
| 261 |
m_LandscapeObject.SetPos(GetVPos()); |
| 262 |
m_LandscapeObject.RenderAmb(); |
| 263 |
devSetZRead(TRUE); |
| 264 |
devSetZWrite(TRUE); |
| 265 |
devSetAmbient(ambient); |
| 266 |
} |
| 267 |
|
| 268 |
/* |
| 269 |
* 環境仕上げ |
| 270 |
*/ |
| 271 |
void CEnvPlugin::RenderAfter(){ |
| 272 |
VEC3 vp = GetVPos(), sd = m_SunObject.GetDir(); |
| 273 |
float flarealpha = (sd.y-m_NightThreshold)*10.0f; |
| 274 |
ValueArea(&flarealpha, 0.0f, 1.0f); |
| 275 |
if(!flarealpha) return; |
| 276 |
V3Norm(&sd, &sd); |
| 277 |
VEC3 sunpos = vp+sd*100.0f; |
| 278 |
devSetTexture(0, NULL); |
| 279 |
devSetZRead(FALSE); |
| 280 |
devSetZWrite(FALSE); |
| 281 |
devSetLighting(FALSE); |
| 282 |
if(g_ConfigMode->GetSunLensFlare()) |
| 283 |
m_SunLensFlare.Render(sunpos, -sd, GetVDir(), flarealpha, -1.0f); |
| 284 |
if(g_ConfigMode->GetSunWhiteout()) m_SunWhiteout.Render(-sd, flarealpha); |
| 285 |
devSetZRead(TRUE); |
| 286 |
devSetZWrite(TRUE); |
| 287 |
devSetLighting(TRUE); |
| 288 |
} |