[2798] | 1 | /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
---|
[2818] | 2 | #include <stdio.h> |
---|
| 3 | #include <string.h> |
---|
[2802] | 4 | |
---|
[2818] | 5 | #include <expat.h> |
---|
| 6 | |
---|
[3465] | 7 | #include <util/FilePath.h> |
---|
[2802] | 8 | |
---|
[1704] | 9 | #include "ParticleSystemFactory.h" |
---|
| 10 | #include "ParticleSystem.h" |
---|
[2376] | 11 | #include "Trace.h" |
---|
[1704] | 12 | |
---|
[3463] | 13 | using namespace nv::util; |
---|
| 14 | |
---|
[1704] | 15 | #define BUFSIZE 4096 |
---|
| 16 | |
---|
| 17 | void ParticleSystemFactory::text(void *data, const XML_Char *txt, int len) |
---|
| 18 | { |
---|
[2818] | 19 | } |
---|
[1704] | 20 | |
---|
| 21 | void ParticleSystemFactory::startElement(void *userData, const char *elementName, const char **attrs) |
---|
| 22 | { |
---|
[2802] | 23 | ParticleSystemFactory* This = reinterpret_cast<ParticleSystemFactory*>(userData); |
---|
[1704] | 24 | |
---|
[2802] | 25 | if (!strcmp(elementName, "particle-sys-info")) { |
---|
| 26 | This->parseParticleSysInfo(attrs); |
---|
| 27 | } else if (!strcmp(elementName, "emitter")) { |
---|
| 28 | This->parseEmitterInfo(attrs); |
---|
| 29 | } |
---|
[1704] | 30 | } |
---|
| 31 | |
---|
| 32 | void ParticleSystemFactory::endElement(void *userData, const char *name) |
---|
| 33 | { |
---|
| 34 | } |
---|
| 35 | |
---|
[2802] | 36 | ParticleSystemFactory::ParticleSystemFactory() : |
---|
| 37 | _newParticleSystem(0) |
---|
[1704] | 38 | { |
---|
| 39 | } |
---|
| 40 | |
---|
| 41 | ParticleSystemFactory::~ParticleSystemFactory() |
---|
| 42 | { |
---|
| 43 | } |
---|
| 44 | |
---|
| 45 | ParticleSystem* ParticleSystemFactory::create(const std::string& fileName) |
---|
| 46 | { |
---|
[2802] | 47 | FILE* fp = fopen(fileName.c_str(), "rb"); |
---|
[1704] | 48 | |
---|
[2802] | 49 | if (fp == 0) { |
---|
| 50 | return 0; |
---|
| 51 | } |
---|
| 52 | XML_Parser parser = XML_ParserCreate(NULL); |
---|
[1704] | 53 | |
---|
[2802] | 54 | XML_SetUserData(parser, this); |
---|
| 55 | XML_SetElementHandler(parser, startElement, endElement); |
---|
[1704] | 56 | |
---|
[2802] | 57 | size_t stat; |
---|
| 58 | size_t cnt; |
---|
[1704] | 59 | |
---|
[2805] | 60 | while (! feof(fp)) { |
---|
[2802] | 61 | void *buff = XML_GetBuffer(parser, BUFSIZE); |
---|
| 62 | if (! buff) { |
---|
| 63 | break; |
---|
| 64 | } |
---|
| 65 | cnt = fread(buff, 1, BUFSIZE, fp); |
---|
| 66 | stat = XML_ParseBuffer(parser, (int) cnt, 0); |
---|
| 67 | if (!stat) { |
---|
[3452] | 68 | //TRACE("Parse error at line %d", XML_GetCurrentLineNumber(parser)); |
---|
[2802] | 69 | break; |
---|
| 70 | } |
---|
| 71 | } |
---|
[1704] | 72 | |
---|
[2802] | 73 | fclose(fp); |
---|
[1704] | 74 | |
---|
[2802] | 75 | XML_ParserFree(parser); |
---|
[1704] | 76 | |
---|
[2802] | 77 | return _newParticleSystem; |
---|
[1704] | 78 | } |
---|
| 79 | |
---|
| 80 | void ParticleSystemFactory::parseParticleSysInfo(const char** attrs) |
---|
| 81 | { |
---|
[2802] | 82 | int width = 2, height = 2; // default |
---|
| 83 | std::string fileName = "J-wire-vec.dx"; |
---|
| 84 | float pointSize = -1.0f; |
---|
| 85 | int numOfUsedParticles = -1; |
---|
| 86 | bool sortEnabled = false; |
---|
[2818] | 87 | bool glyphEnabled = false; |
---|
[2802] | 88 | bool bboxVisible = false; |
---|
| 89 | bool advectionEnabled = false; |
---|
| 90 | bool streamlineEnabled = false; |
---|
| 91 | bool timeVaryingData = false; |
---|
| 92 | int fieldWidth = 1; |
---|
| 93 | int fieldHeight = 1; |
---|
| 94 | int fieldDepth = 1; |
---|
| 95 | // TBD.. |
---|
| 96 | //float timeSeries_vel_mag_min; |
---|
| 97 | //float timeSeries_vel_mag_max; |
---|
| 98 | //float timeSeriesVelMagMax; |
---|
| 99 | int startIndex = -1, endIndex = -1; |
---|
| 100 | for (int i = 0; attrs[i]; i += 2) { |
---|
| 101 | if (!strcmp(attrs[i], "rendertarget-width")) { |
---|
| 102 | width = atoi(attrs[i + 1]); |
---|
| 103 | } else if (!strcmp(attrs[i], "rendertarget-height")) { |
---|
| 104 | height = atoi(attrs[i + 1]); |
---|
| 105 | } else if (!strcmp(attrs[i], "particle-point-size")) { |
---|
| 106 | pointSize = (float) atof(attrs[i + 1]); |
---|
| 107 | } else if (!strcmp(attrs[i], "vector-field-x")) { |
---|
[2814] | 108 | fieldWidth = atoi(attrs[i + 1]); |
---|
[2802] | 109 | } else if (!strcmp(attrs[i], "vector-field-y")) { |
---|
[2814] | 110 | fieldHeight = atoi(attrs[i + 1]); |
---|
[2802] | 111 | } else if (!strcmp(attrs[i], "vector-field-z")) { |
---|
[2814] | 112 | fieldDepth = atoi(attrs[i + 1]); |
---|
[2802] | 113 | } else if (!strcmp(attrs[i], "sort-enabled")) { |
---|
| 114 | if (!strcmp(attrs[i + 1], "true")) |
---|
| 115 | sortEnabled = true; |
---|
[2818] | 116 | } else if (!strcmp(attrs[i], "glyph-enabled")) { |
---|
[2802] | 117 | if (!strcmp(attrs[i + 1], "true")) |
---|
[2818] | 118 | glyphEnabled = true; |
---|
[2802] | 119 | } else if (!strcmp(attrs[i], "bbox-draw-enabled")) { |
---|
| 120 | if (!strcmp(attrs[i + 1], "true")) |
---|
| 121 | bboxVisible = true; |
---|
| 122 | } else if (!strcmp(attrs[i], "advection-enabled")) { |
---|
| 123 | if (!strcmp(attrs[i + 1], "true")) |
---|
| 124 | advectionEnabled = true; |
---|
| 125 | } else if (!strcmp(attrs[i], "stream-line-enabled")) { |
---|
| 126 | if (!strcmp(attrs[i + 1], "true")) |
---|
| 127 | streamlineEnabled = true; |
---|
| 128 | } else if (!strcmp(attrs[i], "vector-field")) { |
---|
| 129 | fileName = attrs[i + 1]; |
---|
| 130 | } else if (!strcmp(attrs[i], "vector-field")) { |
---|
| 131 | if (!strcmp(attrs[i + 1], "true")) |
---|
| 132 | timeVaryingData = true; |
---|
| 133 | } else if (!strcmp(attrs[i], "particle-user-num")) { |
---|
| 134 | numOfUsedParticles = atoi(attrs[i + 1]); |
---|
| 135 | } else if (!strcmp(attrs[i], "time-series-start-index")) { |
---|
| 136 | startIndex = atoi(attrs[i + 1]); |
---|
| 137 | } else if (!strcmp(attrs[i], "time-series-end-index")) { |
---|
| 138 | endIndex = atoi(attrs[i + 1]); |
---|
| 139 | } else if (!strcmp(attrs[i], "time-varying")) { |
---|
| 140 | if (!strcmp(attrs[i + 1], "true")) |
---|
| 141 | timeVaryingData = true; |
---|
| 142 | } |
---|
| 143 | } |
---|
[1704] | 144 | |
---|
[2802] | 145 | if (timeVaryingData) { |
---|
| 146 | char buff[256]; |
---|
| 147 | sprintf(buff, fileName.c_str(), startIndex); |
---|
[3463] | 148 | std::string path = FilePath::getInstance()->getPath(buff); |
---|
[2802] | 149 | if (path.size()) { |
---|
| 150 | std::string dir; |
---|
| 151 | int index = path.rfind('/'); |
---|
| 152 | if (index == -1) { |
---|
| 153 | index = path.rfind('\\'); |
---|
[2822] | 154 | if (index == -1) { |
---|
[3452] | 155 | TRACE("file not found"); |
---|
[2822] | 156 | } |
---|
[2802] | 157 | } |
---|
[1704] | 158 | |
---|
[2802] | 159 | dir = path.substr(0, index + 1); |
---|
| 160 | path = dir + fileName; |
---|
[2818] | 161 | |
---|
| 162 | _newParticleSystem = |
---|
| 163 | new ParticleSystem(width, height, path.c_str(), |
---|
| 164 | fieldWidth, fieldHeight, fieldDepth, |
---|
| 165 | timeVaryingData, startIndex, endIndex); |
---|
[2802] | 166 | } else { |
---|
[2818] | 167 | _newParticleSystem = |
---|
| 168 | new ParticleSystem(width, height, fileName.c_str(), |
---|
| 169 | fieldWidth, fieldHeight, fieldDepth, |
---|
| 170 | timeVaryingData, startIndex, endIndex); |
---|
[2802] | 171 | } |
---|
| 172 | } else { |
---|
[3463] | 173 | std::string path = FilePath::getInstance()->getPath(fileName.c_str()); |
---|
[2818] | 174 | _newParticleSystem = |
---|
| 175 | new ParticleSystem(width, height, path.c_str(), |
---|
| 176 | fieldWidth, fieldHeight, fieldDepth, |
---|
| 177 | timeVaryingData, startIndex, endIndex); |
---|
[2802] | 178 | } |
---|
| 179 | |
---|
| 180 | if (pointSize != -1.0f) _newParticleSystem->setDefaultPointSize(pointSize); |
---|
| 181 | if (sortEnabled) _newParticleSystem->enable(ParticleSystem::PS_SORT); |
---|
[2818] | 182 | if (glyphEnabled) _newParticleSystem->enable(ParticleSystem::PS_GLYPH); |
---|
[2802] | 183 | if (bboxVisible) _newParticleSystem->enable(ParticleSystem::PS_DRAW_BBOX); |
---|
| 184 | if (advectionEnabled) _newParticleSystem->enable(ParticleSystem::PS_ADVECTION); |
---|
| 185 | if (streamlineEnabled) _newParticleSystem->enable(ParticleSystem::PS_STREAMLINE); |
---|
| 186 | if (numOfUsedParticles != -1) _newParticleSystem->setUserDefinedNumOfParticles(numOfUsedParticles); |
---|
[1704] | 187 | } |
---|
| 188 | |
---|
| 189 | void ParticleSystemFactory::parseEmitterInfo(const char** attrs) |
---|
| 190 | { |
---|
[2802] | 191 | ParticleEmitter* emitter = new ParticleEmitter; |
---|
| 192 | for (int i = 0; attrs[i]; i += 2) { |
---|
| 193 | if (!strcmp(attrs[i], "max-position-offset")) { |
---|
| 194 | float x = 0, y = 0, z = 0; |
---|
| 195 | sscanf(attrs[i+1], "%f%f%f",&x, &y, &z); |
---|
| 196 | emitter->setMaxPositionOffset(x, y, z); |
---|
| 197 | } else if (!strcmp(attrs[i], "position")) { |
---|
| 198 | float x = 0, y = 0, z = 0; |
---|
| 199 | sscanf(attrs[i+1], "%f%f%f",&x, &y, &z); |
---|
| 200 | emitter->setPosition(x, y, z); |
---|
| 201 | } else if (!strcmp(attrs[i], "min-max-life-time")) { |
---|
| 202 | float min = 0, max = 0; |
---|
| 203 | sscanf(attrs[i+1], "%f%f",&min, &max); |
---|
| 204 | emitter->setMinMaxLifeTime(min, max); |
---|
| 205 | } else if (!strcmp(attrs[i], "min-max-new-particles")) { |
---|
| 206 | int min = 0, max = 0; |
---|
| 207 | sscanf(attrs[i+1], "%d%d",&min, &max); |
---|
| 208 | emitter->setMinMaxNumOfNewParticles(min, max); |
---|
| 209 | } else if (!strcmp(attrs[i], "enabled")) { |
---|
| 210 | if (!strcmp(attrs[i + 1], "true")) |
---|
| 211 | emitter->setEnabled(true); |
---|
| 212 | else |
---|
| 213 | emitter->setEnabled(false); |
---|
| 214 | } |
---|
| 215 | } |
---|
| 216 | _newParticleSystem->addEmitter(emitter); |
---|
[1704] | 217 | } |
---|