| 1 |
#include "stdafx.h" |
| 2 |
#include "CRailPlugin.h" |
| 3 |
#include "CTiePlugin.h" |
| 4 |
#include "CGirderPlugin.h" |
| 5 |
#include "CRailSelectMode.h" |
| 6 |
#include "CRailBuildMode.h" |
| 7 |
#include "CSimulationMode.h" |
| 8 |
#include "CConfigMode.h" |
| 9 |
|
| 10 |
// 内部定数 |
| 11 |
extern const float RAIL_PREV_LEN = 100.0f; // レールプレビュー長 |
| 12 |
const int WHEEL_SOUND_MARGIN = 100; // 車輪音空白時間 [ms] |
| 13 |
|
| 14 |
// 外部グローバル |
| 15 |
extern float g_FrameDelta; |
| 16 |
extern bool g_EnableCant; |
| 17 |
|
| 18 |
/* |
| 19 |
* [static] |
| 20 |
* プレビュー |
| 21 |
*/ |
| 22 |
void CRailPlugin::RenderPreview(){ |
| 23 |
if(!ms_PreviewState || !(g_Rail || g_Tie || g_Girder)) return; |
| 24 |
VEC3 op1(0.0f, 0.0f, -RAIL_PREV_LEN), op2(0.0f, 0.0f, RAIL_PREV_LEN); |
| 25 |
int i, j, split = 8; |
| 26 |
bool multi = CRailwayMode::IsMultiTrack(); |
| 27 |
int tnum = multi ? CRailwayMode::GetTrackNum() : 1; |
| 28 |
float tint = multi ? CRailwayMode::GetTrackInterval() : 0.0f; |
| 29 |
for(j = 0; j<=tnum; j++){ |
| 30 |
float x = (j-(tnum-1)*0.5f)*tint; |
| 31 |
if(j==tnum){ |
| 32 |
if(!g_Girder || !g_Girder->IsMultiTrack()) break; |
| 33 |
x = 0.0f; |
| 34 |
} |
| 35 |
if(g_Rail) g_Rail->ResetMapTemp(); |
| 36 |
if(g_Tie) g_Tie->ResetMapTemp(); |
| 37 |
if(g_Girder) g_Girder->ResetMapTemp(); |
| 38 |
for(i = 0; i<split; i++){ |
| 39 |
VEC3 op1 = VEC3(x, 0.0f, (i/split-0.5f)*2*RAIL_PREV_LEN); |
| 40 |
VEC3 op2 = VEC3(x, 0.0f, ((i+1)/split-0.5f)*2*RAIL_PREV_LEN); |
| 41 |
VEC3 p1 = op1, ip1 = p1, r1 = V3RIGHT, u1 = V3UP, d1 = V3DIR; |
| 42 |
VEC3 p2 = op2, ip2 = p2, r2 = V3RIGHT, u2 = V3UP, d2 = V3DIR; |
| 43 |
VEC3 gfix; |
| 44 |
float len = V3Len(&(p2-p1)); |
| 45 |
bool g_flag = g_Girder && (g_Girder->IsMultiTrack() ? j==tnum : j<tnum); |
| 46 |
devResetMatrix(); |
| 47 |
devResetMaterial(); |
| 48 |
devSetState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1); |
| 49 |
devSetState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1); |
| 50 |
if(g_Rail){ |
| 51 |
if(j<tnum){ |
| 52 |
g_Rail->Dump(p1, r1, u1, ip1, r1, u1, p2, r2, u2, ip2, r2, u2, len, 7); |
| 53 |
}else{ |
| 54 |
g_Rail->BeforeDump(p1, r1, u1, p2, r2, u2); |
| 55 |
g_Rail->AfterDump(p1, u1, ip1, u1, p2, u2, ip2, u2); |
| 56 |
} |
| 57 |
} |
| 58 |
if(g_Tie){ |
| 59 |
if(j<tnum){ |
| 60 |
g_Tie->Dump(p1, r1, u1, ip1, r1, u1, p2, r2, u2, ip2, r2, u2, len, 7); |
| 61 |
}else{ |
| 62 |
g_Tie->BeforeDump(p1, r1, u1, p2, r2, u2); |
| 63 |
g_Tie->AfterDump(p1, u1, ip1, u1, p2, u2, ip2, u2); |
| 64 |
} |
| 65 |
} |
| 66 |
if(g_flag) g_Girder->Dump( |
| 67 |
p1, r1, u1, ip1, r1, u1, p2, r2, u2, ip2, r2, u2, len, 7); |
| 68 |
p1 = ip1 = op1; p2 = ip2 = op2; |
| 69 |
devSetState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL); |
| 70 |
devSetState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL); |
| 71 |
if(g_Rail){ |
| 72 |
if(j<tnum){ |
| 73 |
g_Rail->Render( |
| 74 |
p1, r1, u1, d1, ip1, r1, u1, p2, r2, u2, d2, ip2, r2, u2, 3, len); |
| 75 |
}else{ |
| 76 |
g_Rail->BeforeDump(p1, r1, u1, p2, r2, u2); |
| 77 |
g_Rail->AfterDump(p1, u1, ip1, u1, p2, u2, ip2, u2); |
| 78 |
} |
| 79 |
} |
| 80 |
if(g_Tie){ |
| 81 |
if(j<tnum){ |
| 82 |
g_Tie->Render( |
| 83 |
p1, r1, u1, d1, ip1, r1, u1, p2, r2, u2, d2, ip2, r2, u2, 3, len); |
| 84 |
}else{ |
| 85 |
g_Tie->BeforeDump(p1, r1, u1, p2, r2, u2); |
| 86 |
g_Tie->AfterDump(p1, u1, ip1, u1, p2, u2, ip2, u2); |
| 87 |
} |
| 88 |
} |
| 89 |
if(g_flag) g_Girder->Render( |
| 90 |
p1, r1, u1, d1, ip1, r1, u1, p2, r2, u2, d2, ip2, r2, u2, 3, len); |
| 91 |
devSetState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1); |
| 92 |
devSetState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1); |
| 93 |
} |
| 94 |
} |
| 95 |
} |
| 96 |
|
| 97 |
/* |
| 98 |
* コンストラクタ |
| 99 |
*/ |
| 100 |
CRailPlugin::CRailPlugin( |
| 101 |
char *id // プラグイン ID |
| 102 |
): |
| 103 |
CProfilePlugin(id) // 基本クラス |
| 104 |
{ |
| 105 |
m_WheelSound = NULL; |
| 106 |
} |
| 107 |
|
| 108 |
/* |
| 109 |
* デストラクタ |
| 110 |
*/ |
| 111 |
CRailPlugin::~CRailPlugin(){ |
| 112 |
DELETE_V(m_WheelSound); |
| 113 |
} |
| 114 |
|
| 115 |
/* |
| 116 |
* ロード |
| 117 |
*/ |
| 118 |
bool CRailPlugin::Load(){ |
| 119 |
char *str = m_Script, *tmp, *eee; |
| 120 |
if(!ChDir() || !m_Script) return false; |
| 121 |
string wheelsound; |
| 122 |
try{ |
| 123 |
if(!(str = BeginBlock(eee = str, "RailInfo"))) throw CSynErr(eee); |
| 124 |
if(!(str = AsgnFloat(eee = str, "Gauge", &m_Gauge))) throw CSynErr(eee); |
| 125 |
if(!(str = AsgnFloat(eee = str, "Height", &m_Height))) throw CSynErr(eee); |
| 126 |
if(!(str = AsgnFloat(eee = str, "SurfaceAlt", &m_SurfaceAlt))) throw CSynErr(eee); |
| 127 |
if(!(str = AsgnFloat(eee = str, "CantRatio", &m_CantRatio))) throw CSynErr(eee); |
| 128 |
m_CantRatio = D3DXToRadian(m_CantRatio); |
| 129 |
if(!(str = AsgnFloat(eee = str, "MaxCant", &m_MaxCant))) throw CSynErr(eee); |
| 130 |
m_MaxCant = tanf(D3DXToRadian(m_MaxCant)); |
| 131 |
if(tmp = AsgnYesNo(eee = str, "FlattenCant", &m_FlattenCant)) str = tmp; |
| 132 |
else m_FlattenCant = false; |
| 133 |
if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK); |
| 134 |
|
| 135 |
if(!(str = BeginBlock(eee = str, "SoundInfo"))) throw CSynErr(eee); |
| 136 |
if(!(str = AsgnString(eee = str, "WheelSoundFile", &wheelsound))) throw CSynErr(eee); |
| 137 |
if(!(str = AsgnFloat(eee = str, "JointInterval", &m_JointInterval))) throw CSynErr(eee); |
| 138 |
if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK); |
| 139 |
|
| 140 |
if(!(str = ReadProfile(eee = str))) throw CSynErr(eee); |
| 141 |
|
| 142 |
if(*(eee = str)) throw CSynErr(eee); |
| 143 |
} |
| 144 |
catch(CSynErr err){ |
| 145 |
HandleError(&err); |
| 146 |
return false; |
| 147 |
} |
| 148 |
LoadData(); |
| 149 |
if(wheelsound.size()){ |
| 150 |
ChDir(); |
| 151 |
m_WheelSound = new CWaveArray; |
| 152 |
m_WheelSound->Load((char *)wheelsound.c_str(), 10, true); |
| 153 |
} |
| 154 |
DELETE_A(m_Buffer); |
| 155 |
return true; |
| 156 |
} |
| 157 |
|
| 158 |
/* |
| 159 |
* プレビュー設定 |
| 160 |
*/ |
| 161 |
void CRailPlugin::SetPreview(){ |
| 162 |
ms_PreviewState = true; |
| 163 |
g_Rail = this; |
| 164 |
string desc = g_Rail->GetBasicInfo(); |
| 165 |
desc += FlashIn("\n%s: %.3f [m]", lang(Gauge), m_Gauge); |
| 166 |
desc += "\n"+g_Rail->GetDescription(); |
| 167 |
g_RailSelectMode->SetProperty((char *)desc.c_str()); |
| 168 |
} |
| 169 |
|
| 170 |
/* |
| 171 |
* ダンプ前処理 |
| 172 |
*/ |
| 173 |
float CRailPlugin::CantFunc( |
| 174 |
float radius // 曲率半径 |
| 175 |
){ |
| 176 |
if(!g_EnableCant) return 0.0f; |
| 177 |
float tmp = m_CantRatio/radius; |
| 178 |
return m_MaxCant*(1.0f-expf(-tmp/m_MaxCant)); |
| 179 |
} |
| 180 |
|
| 181 |
/* |
| 182 |
* 車輪音再生 |
| 183 |
*/ |
| 184 |
void CRailPlugin::PlayWheelSound( |
| 185 |
float dist1, // 距離 1 |
| 186 |
float dist2, // 距離 2 |
| 187 |
VEC3 &pos // 位置 |
| 188 |
){ |
| 189 |
if(!m_WheelSound || !g_ConfigMode->GetRailSound() |
| 190 |
|| g_SimulationMode->GetSimSpeed()>1) return; |
| 191 |
float f1 = dist1/m_JointInterval, f2 = dist2/m_JointInterval; |
| 192 |
int n1 = Round(f1), n2 = Round(f2); |
| 193 |
if(n1!=n2){ |
| 194 |
float delay = (0.5f*(n1+n2)-f1)/(f2-f1); |
| 195 |
ValueArea(&delay, 0.0f, 1.0f); |
| 196 |
delay *= g_FrameDelta>WHEEL_SOUND_MARGIN ? WHEEL_SOUND_MARGIN : g_FrameDelta; |
| 197 |
m_WheelSound->Add(pos, 0, (int)(WHEEL_SOUND_MARGIN-delay)); |
| 198 |
} |
| 199 |
} |
| 200 |
|
| 201 |
/* |
| 202 |
* ダンプ前処理 |
| 203 |
*/ |
| 204 |
void CRailPlugin::BeforeDump( |
| 205 |
VEC3 &p1, VEC3 &r1, VEC3 &u1, // 始点 (正規化済) |
| 206 |
VEC3 &p2, VEC3 &r2, VEC3 &u2 // 終点 (正規化済) |
| 207 |
){ |
| 208 |
float sft1 = 1.0f-sqrtf(r1.x*r1.x+r1.z*r1.z); |
| 209 |
float sft2 = 1.0f-sqrtf(r2.x*r2.x+r2.z*r2.z); |
| 210 |
if(r1.y>0.0f) sft1 = -sft1; |
| 211 |
if(r2.y>0.0f) sft2 = -sft2; |
| 212 |
VEC3 fr1(r1.x, 0.0f, r1.z), fr2(r2.x, 0.0f, r2.z); |
| 213 |
V3Norm(&fr1, &fr1); |
| 214 |
V3Norm(&fr2, &fr2); |
| 215 |
p1 += 0.5f*m_Gauge*(fabsf(r1.y)*V3UP+sft1*fr1); |
| 216 |
p2 += 0.5f*m_Gauge*(fabsf(r2.y)*V3UP+sft2*fr2); |
| 217 |
} |
| 218 |
|
| 219 |
/* |
| 220 |
* ダンプ後処理 |
| 221 |
*/ |
| 222 |
void CRailPlugin::AfterDump( |
| 223 |
VEC3 &p1, VEC3 &u1, // 始点 (正規化済) |
| 224 |
VEC3 &ip1, VEC3 &iu1, // 非カント始点 (正規化済) |
| 225 |
VEC3 &p2, VEC3 &u2, // 終点 (正規化済) |
| 226 |
VEC3 &ip2, VEC3 &iu2 // 非カント終点 (正規化済) |
| 227 |
){ |
| 228 |
ip1 -= m_Height*iu1; |
| 229 |
ip2 -= m_Height*iu2; |
| 230 |
if(m_FlattenCant){ |
| 231 |
p1 = ip1; u1 = iu1; |
| 232 |
p2 = ip2; u2 = iu2; |
| 233 |
}else{ |
| 234 |
p1 -= m_Height*u1; |
| 235 |
p2 -= m_Height*u2; |
| 236 |
} |
| 237 |
} |
| 238 |
|
| 239 |
/* |
| 240 |
* 橋脚設置位置計算 |
| 241 |
*/ |
| 242 |
void CRailPlugin::CalcPierPos( |
| 243 |
VEC3 *pos, // 位置 |
| 244 |
VEC3 *right, // right (正規化済) |
| 245 |
VEC3 *up, // up (正規化済) |
| 246 |
VEC3 *dir // dir (正規化済) |
| 247 |
){ |
| 248 |
if(m_FlattenCant){ |
| 249 |
right->y = 0.0f; |
| 250 |
V3Norm(up, V3Cross(up, dir, V3Norm(right, right))); |
| 251 |
} |
| 252 |
*pos -= *up*m_Height; |
| 253 |
} |