36 LOG(
"[RoR] Loading skidmarks.cfg...");
39 Ogre::DataStreamPtr ds = Ogre::ResourceGroupManager::getSingleton().openResource(
"skidmarks.cfg",
RGN_CONFIG);
40 Ogre::String currentModel =
"";
45 Ogre::StringUtil::trim(line);
47 if (line.empty() || line[0] ==
';')
50 Ogre::StringVector args = Ogre::StringUtil::split(line,
",");
59 if (currentModel !=
"")
62 RoR::Log(
"[RoR] skidmarks.cfg loaded OK");
64 catch (Ogre::Exception& e)
66 RoR::LogFormat(
"[RoR] Error loading skidmarks.cfg (%s)", e.getFullDescription().c_str());
80 Ogre::StringUtil::trim(cfg.
ground);
82 Ogre::StringUtil::trim(cfg.
texture);
84 cfg.
slipFrom = Ogre::StringConverter::parseReal(args[2]);
85 cfg.
slipTo = Ogre::StringConverter::parseReal(args[3]);
87 if (!m_models.size() || m_models.find(modelName) == m_models.end())
88 m_models[modelName] = std::vector<SkidmarkDef>();
90 m_models[modelName].push_back(cfg);
96 if (m_models.find(model) == m_models.end())
98 for (std::vector<SkidmarkDef>::iterator it = m_models[model].begin(); it != m_models[model].end(); it++)
100 if (it->ground == ground && it->slipFrom <= slip && it->slipTo > slip)
102 texture = it->texture.c_str();
110 Ogre::Vector2
RoR::Skidmark::m_tex_coords[4] = {Ogre::Vector2(0, 0), Ogre::Vector2(0, 1), Ogre::Vector2(1, 0), Ogre::Vector2(1, 1)};
113 Ogre::SceneNode* snode,
int m_length ,
int m_bucket_count )
114 : m_scene_node(snode)
117 , m_bucket_count(m_bucket_count)
119 , m_min_distance(0.25f)
120 , m_max_distance(std::max(0.5f, m_wheel->wh_width * 1.1f))
142 char bname[256] =
"";
143 sprintf(bname,
"mat-skidmark-%d", m_instance_counter);
144 skid.
material = Ogre::MaterialManager::getSingleton().create(bname, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
145 Ogre::Pass* p = skid.
material->getTechnique(0)->getPass(0);
147 p->createTextureUnitState(texture);
148 p->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
149 p->setLightingEnabled(
false);
150 p->setDepthWriteEnabled(
false);
151 p->setDepthBias(3, 3);
152 p->setCullingMode(Ogre::CULL_NONE);
154 skid.
points.resize(m_length);
158 skid.
obj->setDynamic(
true);
159 skid.
obj->setRenderingDistance(800);
160 skid.
obj->begin(bname, Ogre::RenderOperation::OT_TRIANGLE_STRIP);
161 for (
int i = 0; i < m_length; i++)
166 skid.
obj->position(start);
167 skid.
obj->textureCoord(0, 0);
170 m_scene_node->attachObject(skid.
obj);
172 m_objects.push(skid);
174 this->LimitObjects();
182 Ogre::MaterialManager::getSingleton().remove(skid.
material->getName());
190 if ((
int)m_objects.size() > m_bucket_count)
198 m_objects.back().points[index] = value;
199 m_objects.back().faceSizes[index] = fsize;
200 m_objects.back().groundTexture[index] = texture;
207 Ogre::Vector3 thisPoint = contact_point;
208 Ogre::Vector3 axis = m_wheel->wh_axis_node_1->RelPosition - m_wheel->wh_axis_node_0->RelPosition;
213 Ogre::Vector3 thisPointAV = thisPoint + axis * 0.5f;
214 Ogre::Real distance = 0;
215 Ogre::Real maxDist = m_max_distance;
216 Ogre::String texture =
"none";
217 m_config->getTexture(
"default", ground_model_name, slip, texture);
220 if (texture ==
"none")
223 if (m_wheel->wh_speed > 1)
224 maxDist *= m_wheel->wh_speed;
226 if (!m_objects.size())
229 this->AddObject(thisPoint, texture);
238 if (distance < m_min_distance)
248 if (distance > maxDist)
251 this->AddObject(thisPoint, texture);
256 Ogre::Vector3 lp1 = m_objects.back().points[m_objects.back().pos - 1];
257 Ogre::Vector3 lp2 = m_objects.back().points[m_objects.back().pos - 2];
258 this->AddObject(lp1, texture);
259 this->AddPoint(lp2, distance, texture);
260 this->AddPoint(lp1, distance, texture);
270 if (distance > maxDist)
273 this->AddObject(thisPoint, texture);
278 Ogre::Vector3 lp1 = m_objects.back().points[m_objects.back().pos - 1];
279 Ogre::Vector3 lp2 = m_objects.back().points[m_objects.back().pos - 2];
280 this->AddObject(lp1, texture);
281 this->AddPoint(lp2, distance, texture);
282 this->AddPoint(lp1, distance, texture);
285 else if (distance > m_max_distance)
288 this->AddObject(thisPoint, texture);
293 const float overaxis = 0.2f;
295 this->AddPoint(contact_point - (axis * overaxis), distance, texture);
296 this->AddPoint(contact_point + axis + (axis * overaxis), distance, texture);
299 m_objects.back().lastPointAv = thisPointAV;
304 if (m_objects.back().pos >= m_length)
308 this->SetPointInt(m_objects.back().pos, value, fsize, texture);
309 m_objects.back().pos++;
314 while (m_objects.size() != 0)
320 this->UpdatePoint(contact_point, index, slip, ground_model_name);
323 if (!m_objects.size())
326 Ogre::Vector3 vaabMin = skid.
points[0];
327 Ogre::Vector3 vaabMax = skid.
points[0];
328 skid.
obj->beginUpdate(0);
329 bool behindEnd =
false;
330 Ogre::Vector3 lastValid = Ogre::Vector3::ZERO;
332 float tcox_counter = 0;
334 for (
int i = 0; i < m_length; i++ , to_counter++)
343 tcox_counter += skid.
faceSizes[i] / m_min_distance;
345 while (tcox_counter > 1)
350 skid.
obj->position(lastValid);
351 skid.
obj->textureCoord(0, 0);
357 Ogre::Vector2 tco = m_tex_coords[to_counter];
358 tco.x *= skid.
faceSizes[i] / m_min_distance;
359 skid.
obj->textureCoord(tco);
361 lastValid = skid.
points[i];
364 if (skid.
points[i].x < vaabMin.x)
365 vaabMin.x = skid.
points[i].x;
366 if (skid.
points[i].y < vaabMin.y)
367 vaabMin.y = skid.
points[i].y;
368 if (skid.
points[i].z < vaabMin.z)
369 vaabMin.z = skid.
points[i].z;
370 if (skid.
points[i].x > vaabMax.x)
371 vaabMax.x = skid.
points[i].x;
372 if (skid.
points[i].y > vaabMax.y)
373 vaabMax.y = skid.
points[i].y;
374 if (skid.
points[i].z > vaabMax.z)
375 vaabMax.z = skid.
points[i].z;
379 skid.
obj->setBoundingBox(Ogre::AxisAlignedBox(vaabMin, vaabMax));