📄 ch18p2_particleemitter.cpp
字号:
void CParticleEmitter::WriteProperty(FILE *file, const char *strName, D3DXCOLOR &value)
{
fprintf(file, "%s=(%.4f, %.4f, %.4f, %.4f)\n", strName, value.r, value.g, value.b, value.a);
}
void CParticleEmitter::WriteProperty(FILE *file, const char *strName, D3DXVECTOR3 &value)
{
fprintf(file, "%s=(%.4f, %.4f, %.4f)\n", strName, value.x, value.y, value.z);
}
void CParticleEmitter::WriteProperty(FILE *file, const char *strName, CMinMax<float> &value)
{
fprintf(file, "%s=(%.4f, %.4f)\n", strName, value.m_Min, value.m_Max);
}
void CParticleEmitter::WriteProperty(FILE *file, const char *strName, int value)
{
fprintf(file, "%s=%d\n", strName, value);
}
void CParticleEmitter::WriteProperty(FILE *file, const char *strName, const char *value)
{
fprintf(file, "%s=%s\n", strName, value);
}
void CParticleEmitter::WriteBlendModeProperty(FILE *file, const char *strName, int value)
{
for (int q=0; q < NUMBLENDINGMODES; q++) {
if (m_BlendingModes[q].mode == value) {
fprintf(file, "%s=%s\n", strName, m_BlendingModes[q].name);
return;
}
}
throw("Invalid Blending Mode.");
}
void CParticleEmitter::GetRightSideFromValueMap(std::map<std::string, std::string> &valuemap,
const char *strName, char *dest, int destsize)
{
std::string str;
if (valuemap.find(strName) == valuemap.end()) {
std::string errorstr;
errorstr = std::string("Missing property \"") + std::string(strName) + std::string("\"!");
throw(errorstr);
}
strncpy(dest, valuemap[strName].c_str(), destsize);
}
void CParticleEmitter::ReadProperty(std::map<std::string, std::string> &valuemap,
const char *strName, D3DXCOLOR &value)
{
char buf[256]; char token[256]; float r,g,b,a;
GetRightSideFromValueMap(valuemap, strName, buf, sizeof(buf));
// color is in the form (R,G,B,A)
PluckFirstField(buf, token, sizeof(token), "("); // skip first (
PluckFirstField(buf, token, sizeof(token), ","); r = atof(token);
PluckFirstField(buf, token, sizeof(token), ","); g = atof(token);
PluckFirstField(buf, token, sizeof(token), ","); b = atof(token);
PluckFirstField(buf, token, sizeof(token), ")"); a = atof(token);
value = D3DXCOLOR(r,g,b,a);
}
void CParticleEmitter::ReadProperty(std::map<std::string, std::string> &valuemap,
const char *strName, D3DXVECTOR3 &value)
{
char buf[256]; char token[256]; float x,y,z;
GetRightSideFromValueMap(valuemap, strName, buf, sizeof(buf));
// vector is in the form (x,y,z)
PluckFirstField(buf, token, sizeof(token), "("); // skip first (
PluckFirstField(buf, token, sizeof(token), ","); x = atof(token);
PluckFirstField(buf, token, sizeof(token), ","); y = atof(token);
PluckFirstField(buf, token, sizeof(token), ")"); z = atof(token);
value = D3DXVECTOR3(x,y,z);
}
void CParticleEmitter::ReadProperty(std::map<std::string, std::string> &valuemap,
const char *strName, CMinMax<float> &value)
{
char buf[256]; char token[256]; float minvalue,maxvalue;
GetRightSideFromValueMap(valuemap, strName, buf, sizeof(buf));
// minmax is in the form (min,max)
PluckFirstField(buf, token, sizeof(token), "("); // skip first (
PluckFirstField(buf, token, sizeof(token), ","); minvalue = atof(token);
PluckFirstField(buf, token, sizeof(token), ")"); maxvalue = atof(token);
value = CMinMax<float>(minvalue,maxvalue);
}
void CParticleEmitter::ReadProperty(std::map<std::string, std::string> &valuemap,
const char *strName, int &value)
{
char buf[256];
GetRightSideFromValueMap(valuemap, strName, buf, sizeof(buf));
value = atoi(buf);
}
void CParticleEmitter::ReadProperty(std::map<std::string, std::string> &valuemap,
const char *strName, std::string &value)
{
char buf[256];
GetRightSideFromValueMap(valuemap, strName, buf, sizeof(buf));
value = buf;
}
void CParticleEmitter::ReadBlendModeProperty(std::map<std::string, std::string> &valuemap,
const char *strName, int &value)
{
char buf[256];
GetRightSideFromValueMap(valuemap, strName, buf, sizeof(buf));
for (int q=0; q < NUMBLENDINGMODES; q++) {
if (!stricmp(m_BlendingModes[q].name, buf)) {
value = m_BlendingModes[q].mode;
return;
}
}
throw("Invalid Blending Mode.");
}
bool CParticleEmitter::Save(const char *strFilename)
{
try {
FILE *file = fopen(strFilename, "wt");
fprintf(file, "[ParticleSystem 1.00]\n");
WriteProperty(file, "Position", m_vPos);
WriteProperty(file, "Gravity", m_vGravity);
WriteProperty(file, "SpawnDir1", m_vSpawnDir1);
WriteProperty(file, "SpawnDir2", m_vSpawnDir2);
WriteProperty(file, "StartColor1", m_StartColor1);
WriteProperty(file, "StartColor2", m_StartColor2);
WriteProperty(file, "EndColor1", m_EndColor1);
WriteProperty(file, "EndColor2", m_EndColor2);
WriteProperty(file, "EmitRate", m_fEmitRate);
WriteProperty(file, "EmitRadius", m_vEmitRadius);
WriteProperty(file, "Lifetime", m_fLifetime);
WriteProperty(file, "Size", m_fSize);
WriteBlendModeProperty(file, "SrcBlend", m_iSrcBlendMode);
WriteBlendModeProperty(file, "DestBlend", m_iDestBlendMode);
WriteProperty(file, "MaxParticles", m_iMaxParticles);
WriteProperty(file, "Texture", m_strTexFilename.c_str());
fclose(file);
}
catch(std::string e) {
m_strLastError = e;
return(false);
}
catch(...) {
m_strLastError = "Unknown error.";
return(false);
}
return(true);
}
bool CParticleEmitter::Load(const char *strFilename)
{
FILE *file = fopen(strFilename, "rt");
if (file == NULL) { throw("Can't open file! (invalid filename?)"); }
try {
char buf[256];
char leftside[256];
char rightside[256];
std::map<std::string, std::string> valuemap;
// read first line - should be [ParticleSystem 1.00]
fgets(buf, sizeof(buf), file);
if (strstr(buf, "[ParticleSystem 1.00]") == NULL) {
throw("Invalid Header (missing \"[ParticleSystem 1.00]\")");
}
// read the entire contents of file into a map. If we read
// more than 100 lines, we assume something's wrong and we
// bail out.
int count=0;
while (!feof(file) && count < 1000) {
// read a line
fgets(buf, sizeof(buf), file);
// if there's something on that line,
if (strlen(buf) >= 2) {
// seperate that line into left and right side of = sign
memset(leftside, 0, sizeof(leftside));
memset(rightside, 0, sizeof(rightside));
PluckFirstField(buf, leftside, sizeof(leftside), "=");
PluckFirstField(buf, rightside, sizeof(rightside), "\n");
// make sure the stuff to the left of the = sign isn't currently
// in the map (if it is, throw an error).
if (valuemap.find(leftside) != valuemap.end()) {
throw("Duplicate value encountered.");
}
// insert left and right sides into map.
valuemap.insert(std::make_pair(std::string(leftside), std::string(rightside)));
}
// increment safety count
count++;
}
if (count == 1000) {
throw("File too big (most likely not a particle system file)");
}
ReadProperty(valuemap, "Position", m_vPos);
ReadProperty(valuemap, "Gravity", m_vGravity);
ReadProperty(valuemap, "SpawnDir1", m_vSpawnDir1);
ReadProperty(valuemap, "SpawnDir2", m_vSpawnDir2);
ReadProperty(valuemap, "StartColor1", m_StartColor1);
ReadProperty(valuemap, "StartColor2", m_StartColor2);
ReadProperty(valuemap, "EndColor1", m_EndColor1);
ReadProperty(valuemap, "EndColor2", m_EndColor2);
ReadProperty(valuemap, "EmitRate", m_fEmitRate);
ReadProperty(valuemap, "EmitRadius", m_vEmitRadius);
ReadProperty(valuemap, "Lifetime", m_fLifetime);
ReadProperty(valuemap, "Size", m_fSize);
ReadBlendModeProperty(valuemap, "SrcBlend", m_iSrcBlendMode);
ReadBlendModeProperty(valuemap, "DestBlend", m_iDestBlendMode);
ReadProperty(valuemap, "MaxParticles", m_iMaxParticles);
ReadProperty(valuemap, "Texture", m_strTexFilename);
fclose(file);
}
catch(const char *e) {
fclose(file);
m_strLastError = e;
return(false);
}
catch(...) {
fclose(file);
m_strLastError = "Unknown error.";
return(false);
}
return(true);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -