- start work on cars lights (patch by Icystar)

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@7074 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: bf61d6c527551300ecddefa5a7c116f11f769a52
Former-commit-id: 4e58e32da7d194fb0b87a9b7ba26feddb80e8e55
This commit is contained in:
torcs-ng 2020-05-17 20:53:02 +00:00
parent 826085435e
commit 2ce184fb36
11 changed files with 576 additions and 25 deletions

View file

@ -1,11 +1,12 @@
INCLUDE(../../../../cmake/macros.cmake)
SET(OSGGRAPH_HEADERS Utils/OsgVectorArrayAdapter.h
Utils/OsgAtomic.h
Utils/OsgAtomic.h
Utils/OsgColor.h
Utils/OsgMath.h
Utils/OsgNodeMask.h
#Utils/OsgOptions.h
Utils/OsgLightTransform.h
#Utils/OsgOptions.h
Sky/OsgSphere.h
Sky/OsgSun.h
@ -20,18 +21,19 @@ SET(OSGGRAPH_HEADERS Utils/OsgVectorArrayAdapter.h
Loader/ReaderWriterACC.h
Loader/OsgLoader.h
Scenery/OsgScenery.h
Scenery/OsgScenery.h
Render/OsgRender.h
Render/OsgReflectionMapping.h
Render/OsgShader.h
Viewer/OsgView.h
Viewer/OsgView.h
Viewer/OsgScreens.h
Viewer/OsgCamera.h
Viewer/OsgHUD.h
Viewer/OsgHUD.h
Viewer/OsgDebugHUD.h
Car/OsgCar.h
Car/OsgCarLight.h
Car/OsgWheel.h
Car/OsgBrake.h
@ -44,7 +46,8 @@ IF(OPTION_SDL2)
ENDIF(OPTION_SDL2)
SET(OSGGRAPH_SOURCES Utils/OsgMath.cpp
#Utils/OsgOptions.cpp
Utils/OsgLightTransform.cpp
#Utils/OsgOptions.cpp
Sky/OsgSphere.cpp
Sky/OsgSun.cpp
@ -61,19 +64,20 @@ SET(OSGGRAPH_SOURCES Utils/OsgMath.cpp
Scenery/OsgBackground.cpp
Scenery/OsgPit.cpp
Scenery/OsgTrackLight.cpp
Scenery/OsgTrackLight.cpp
Scenery/OsgScenery.cpp
Render/OsgRender.cpp
Render/OsgReflectionMapping.cpp
Render/OsgShader.cpp
Viewer/OsgView.cpp
Viewer/OsgView.cpp
Viewer/OsgScreens.cpp
Viewer/OsgCamera.cpp
Viewer/OsgHUD.cpp
Viewer/OsgHUD.cpp
Viewer/OsgDebugHUD.cpp
Car/OsgCar.cpp
Car/OsgCarLight.cpp
Car/OsgWheel.cpp
Car/OsgBrake.cpp

View file

@ -74,6 +74,9 @@ SDCar::SDCar(void) :
SDCar::~SDCar(void)
{
if (lights_branch)
((SDCarLights*)getCarLights())->getLightsRoot()->removeChild(lights_branch);
if(car_root != NULL)
{
car_root->removeChildren(0, car_root->getNumChildren());
@ -84,6 +87,63 @@ SDCar::~SDCar(void)
delete reflectionMapping;
}
void SDCar::loadCarLights(tCarElt *Car)
{
SDCarLights *carLights = (SDCarLights*)getCarLights();
if (lights_branch)
carLights->getLightsRoot()->removeChild(lights_branch);
lights_branch = new osg::MatrixTransform;
char path[1024] = {};
void *handle = Car->_carHandle;
snprintf(path, 1023, "%s/%s", SECT_GROBJECTS, SECT_LIGHT);
int lightNum = GfParmGetEltNb(handle, path);
for (int i = 0; i < lightNum; i++) {
snprintf(path, 1023, "%s/%s/%d", SECT_GROBJECTS, SECT_LIGHT, i + 1);
osg::Vec3d position;
position[0] = GfParmGetNum(handle, path, PRM_XPOS, NULL, 0);
position[1] = GfParmGetNum(handle, path, PRM_YPOS, NULL, 0);
position[2] = GfParmGetNum(handle, path, PRM_ZPOS, NULL, 0);
osg::Vec3d normal;
normal[0] = position[0] > 0 ? 1 : -1;
const char *typeName = GfParmGetStr(handle, path, PRM_TYPE, "");
CarLightType type = CAR_LIGHT_TYPE_NONE;
if (!strcmp(typeName, VAL_LIGHT_HEAD1)) {
type = CAR_LIGHT_TYPE_FRONT;
} else
if (!strcmp(typeName, VAL_LIGHT_HEAD2)) {
type = CAR_LIGHT_TYPE_FRONT2;
} else
if (!strcmp(typeName, VAL_LIGHT_BRAKE)) {
type = CAR_LIGHT_TYPE_BRAKE;
} else
if (!strcmp(typeName, VAL_LIGHT_BRAKE2)) {
type = CAR_LIGHT_TYPE_BRAKE2;
} else
if (!strcmp(typeName, VAL_LIGHT_REAR)) {
type = CAR_LIGHT_TYPE_REAR;
} else
if (!strcmp(typeName, VAL_LIGHT_REVERSE)) {
type = CAR_LIGHT_TYPE_REVERSE;
}
double size = GfParmGetNum(handle, path, PRM_SIZE, NULL, 0.2);
osg::ref_ptr<osg::StateSet> state_set = carLights->getStateSet(type);
SDCarLight light;
lights_branch->addChild( light.init(type, state_set, position, normal, size, 4) );
lights.push_back(light);
}
lights_branch->setMatrix( car_branch->getMatrix() );
carLights->getLightsRoot()->addChild(lights_branch);
}
osg::ref_ptr<osg::Node> SDCar::loadCar(tCarElt *Car, bool tracktype, bool subcat, int carshader)
{
this->car_branch = new osg::MatrixTransform;
@ -665,6 +725,8 @@ osg::ref_ptr<osg::Node> SDCar::loadCar(tCarElt *Car, bool tracktype, bool subcat
this->reflectionMapping = new SDReflectionMapping(this);
this->setReflectionMap(this->reflectionMapping->getReflectionMap());
loadCarLights(Car);
return this->car_root;
}
@ -682,11 +744,6 @@ int SDCar::getReflectionMappingMethod()
return this->reflectionMappingMethod;
}
tCarElt *SDCar::getCar()
{
return car;
}
/*#define GR_SHADOW_POINTS 6
#define MULT 1.1
osg::ref_ptr<osg::Node> SDCar::initOcclusionQuad(tCarElt *car)
@ -775,11 +832,13 @@ void SDCar::markCarCurrent(tCarElt *Car)
if(this->car == Car)
{
car_branch->setNodeMask(NODE_MASK_CURCAR);
lights_branch->setNodeMask(NODE_MASK_CURCAR);
pDriver->setNodeMask(NODE_MASK_CURDRV);
}
else
{
car_branch->setNodeMask(NODE_MASK_ALL);
lights_branch->setNodeMask(NODE_MASK_ALL);
pDriver->setNodeMask(NODE_MASK_ALL);
}
}
@ -855,6 +914,9 @@ void SDCar::updateCar()
movt->addChild(pSteer);
}
for(std::vector<SDCarLight>::iterator i = lights.begin(); i != lights.end(); ++i)
i->update(*this);
if(_light)
{
if(car->_lightCmd)
@ -874,6 +936,7 @@ void SDCar::updateCar()
wheels.updateWheels();
this->car_branch->setMatrix(mat);
this->lights_branch->setMatrix(mat);
if(_carShader > 2)
reflectionMapping->update();

View file

@ -29,6 +29,8 @@
#include "OsgDriver.h"
#include "OsgWheel.h"
#include "OsgCarLight.h"
class SDCarShader;
class SDReflectionMapping;
@ -38,6 +40,7 @@ class SDCar
{
private :
osg::ref_ptr<osg::MatrixTransform> car_branch;
osg::ref_ptr<osg::MatrixTransform> lights_branch;
osg::ref_ptr<osg::Group> car_shaded_body;
osg::ref_ptr<osg::Group> car_root;
osg::ref_ptr<osg::Switch> pLight;
@ -49,6 +52,8 @@ private :
//osg::ref_ptr<osg::Geometry> quad;
//osg::ref_ptr<osg::Node> initOcclusionQuad(tCarElt *car);
std::vector<SDCarLight> lights;
tCarElt *car;
SDWheels wheels;
@ -58,6 +63,8 @@ private :
int reflectionMappingMethod;
void setReflectionMap(osg::ref_ptr<osg::Texture> map);
void loadCarLights(tCarElt *Car);
public :
SDCar(void);
~SDCar(void);
@ -77,7 +84,8 @@ public :
int getReflectionMappingMethod();
tCarElt *getCar();
tCarElt *getCar() { return car; }
const tCarElt *getCar() const { return car; }
void markCarCurrent(tCarElt *Car);
void updateCar();

View file

@ -0,0 +1,181 @@
/***************************************************************************
file : OsgCarLight.cpp
created : Tue Mar 31 15:34:18 CEST 2020
......... : ...2020 Ivan Mahonin
email : bh@icystar.com
version : $Id$
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <osg/PolygonOffset>
#include <osg/TexEnv>
#include <osg/Depth>
#include "OsgLoader.h"
#include "OsgLightTransform.h"
#include "OsgNodeMask.h"
#include "OsgCarLight.h"
#include "OsgCar.h"
osg::ref_ptr<osg::Node> SDCarLight::init(
CarLightType type,
osg::ref_ptr<osg::StateSet> state_set,
const osg::Vec3d &position,
const osg::Vec3d &normal,
double size,
int layers )
{
if (layers < 0) layers = 0;
this->type = type;
osg::ref_ptr<SDLightTransform> transform = new SDLightTransform;
transform->setPosition(position);
transform->setNormal(normal);
transform->setMatrix(osg::Matrix::scale(size, size, size));
if (layers > 0) {
const osg::Vec3d vtx[] = {
osg::Vec3d(-0.5,-0.5, 2.0),
osg::Vec3d( 0.5,-0.5, 2.0),
osg::Vec3d(-0.5, 0.5, 2.0),
osg::Vec3d( 0.5, 0.5, 2.0) };
const osg::Vec2d tex[] = {
osg::Vec2d(0.0, 0.0),
osg::Vec2d(1.0, 0.0),
osg::Vec2d(0.0, 1.0),
osg::Vec2d(1.0, 1.0) };
// build triangle strip
const int count = (layers+1)*2;
osg::Vec3dArray *vertexArray = new osg::Vec3dArray;
osg::Vec2dArray *texArray = new osg::Vec2dArray;
for(int i = 0; i < count; ++i) {
const int j = i%4;
vertexArray->push_back(vtx[j]);
texArray->push_back(tex[j]);
}
osg::Vec4dArray *colorArray = new osg::Vec4dArray;
colorArray->push_back( osg::Vec4d(0.8, 0.8, 0.8, 0.75) );
osg::Vec3dArray *normalArray = new osg::Vec3dArray;
normalArray->push_back( osg::Vec3d(0.0, 0.0, -1.0) );
osg::Geometry *geometry = new osg::Geometry;
geometry->setVertexArray(vertexArray);
geometry->setTexCoordArray(0, texArray, osg::Array::BIND_PER_VERTEX);
geometry->setNormalArray(normalArray, osg::Array::BIND_OVERALL);
geometry->setColorArray(colorArray, osg::Array::BIND_OVERALL);
geometry->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, 0, count) );
osg::Geode *geode = new osg::Geode;
geode->addDrawable(geometry);
geode->setStateSet(state_set);
transform->addChild(geode);
}
node = transform;
return node;
}
void SDCarLight::update(const SDCar &car)
{
const tCarElt *carElt = car.getCar();
bool visible = false;
switch (type) {
case CAR_LIGHT_TYPE_BRAKE:
case CAR_LIGHT_TYPE_BRAKE2:
if (carElt->_brakeCmd>0 || carElt->_ebrakeCmd>0)
visible = true;
break;
case CAR_LIGHT_TYPE_FRONT:
if (carElt->_lightCmd & RM_LIGHT_HEAD1)
visible = true;
break;
case CAR_LIGHT_TYPE_FRONT2:
if (carElt->_lightCmd & RM_LIGHT_HEAD2)
visible = true;
break;
case CAR_LIGHT_TYPE_REAR:
if ((carElt->_lightCmd & RM_LIGHT_HEAD1) ||
(carElt->_lightCmd & RM_LIGHT_HEAD2))
visible = true;
break;
case CAR_LIGHT_TYPE_REAR2:
if ((carElt->_lightCmd & RM_LIGHT_HEAD1) ||
(carElt->_lightCmd & RM_LIGHT_HEAD2))
visible = true;
break;
default:
break;
}
node->setNodeMask(visible ? NODE_MASK_ALL : NODE_MASK_NONE);
}
void SDCarLights::loadStates()
{
const static char *filenames[CAR_LIGHT_TYPE_COUNT] = {
NULL,
"frontlight1.png",
"frontlight2.png",
"rearlight1.png",
"rearlight2.png",
"breaklight1.png",
"breaklight2.png",
NULL
};
osgLoader loader;
loader.AddSearchPath("data/textures");
loader.AddSearchPath("data/img");
loader.AddSearchPath(".");
for(int i = 0; i < CAR_LIGHT_TYPE_COUNT; ++i) {
state_sets[i].release();
if (!filenames[i])
continue;
osg::ref_ptr<osg::Image> image = loader.LoadImageFile(filenames[i]);
if (!image) {
GfLogError("Failed to load car lights texture: %s\n", filenames[i]);
continue;
}
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
texture->setDataVariance(osg::Object::STATIC);
texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE);
texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE);
texture->setImage(image);
osg::ref_ptr<osg::StateSet> state_set = new osg::StateSet;
state_set->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED);
state_set->setMode(GL_CULL_FACE, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED);
state_set->setMode(GL_BLEND, osg::StateAttribute::ON);
state_set->setMode(GL_FOG, osg::StateAttribute::ON);
state_set->setMode(GL_ALPHA_TEST, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED);
state_set->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
state_set->setAttributeAndModes(new osg::PolygonOffset(-15.f, -20.f), osg::StateAttribute::ON);
state_set->setAttributeAndModes(new osg::TexEnv(osg::TexEnv::MODULATE), osg::StateAttribute::ON);
state_set->setAttributeAndModes(new osg::Depth(osg::Depth::LESS, 0.0, 1.0, false), osg::StateAttribute::ON);
state_set->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
state_sets[i] = state_set;
}
}

View file

@ -0,0 +1,86 @@
/***************************************************************************
file : OsgCarLight.h
created : Tue Mar 31 15:32:14 CEST 2020
......... : ...2020 Ivan Mahonin
email : bh@icystar.com
version : $Id$
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef _OSGCARLIGHT_H_
#define _OSGCARLIGHT_H_
#include <osg/Group>
#include <osg/StateSet>
enum CarLightType
{
CAR_LIGHT_TYPE_NONE = 0,
CAR_LIGHT_TYPE_FRONT = 1,
CAR_LIGHT_TYPE_FRONT2 = 2,
CAR_LIGHT_TYPE_REAR = 3,
CAR_LIGHT_TYPE_REAR2 = 4,
CAR_LIGHT_TYPE_BRAKE = 5,
CAR_LIGHT_TYPE_BRAKE2 = 6,
CAR_LIGHT_TYPE_REVERSE = 7
};
enum { CAR_LIGHT_TYPE_COUNT = 8 };
class SDCar;
class SDCarLight {
private:
CarLightType type;
osg::ref_ptr<osg::Node> node;
public:
SDCarLight() {}
~SDCarLight() {}
CarLightType get_type() const { return type; }
osg::ref_ptr<osg::Node> init(
CarLightType type,
osg::ref_ptr<osg::StateSet> state_set,
const osg::Vec3d &position,
const osg::Vec3d &normal,
double size,
int layers );
void update(const SDCar &car);
};
class SDCarLights
{
private:
osg::ref_ptr<osg::Group> lights_root;
osg::ref_ptr<osg::StateSet> state_sets[CAR_LIGHT_TYPE_COUNT];
public:
SDCarLights(): lights_root(new osg::Group) {}
~SDCarLights() {}
void loadStates();
osg::ref_ptr<osg::Group> getLightsRoot()
{ return lights_root; }
osg::ref_ptr<osg::StateSet> getStateSet(CarLightType type)
{ return state_sets[(int)type > 0 && (int)type < CAR_LIGHT_TYPE_COUNT ? type : 0]; }
};
#endif

View file

@ -31,6 +31,7 @@
#include "OsgMain.h"
//#include "OsgOptions.h"
#include "OsgCar.h"
#include "OsgCarLight.h"
#include "OsgScenery.h"
#include "OsgRender.h"
#include "OsgMath.h"
@ -41,6 +42,7 @@
//extern osg::Timer_t m_start_tick;
//SDOptions *Options = 0;
SDCarLights *carLights = 0;
SDCars *cars = 0;
SDScenery *scenery = 0;
SDRender *render = 0;
@ -69,6 +71,11 @@ void * getCars()
return cars;
}
void * getCarLights()
{
return carLights;
}
void * getScenery()
{
return scenery;
@ -248,7 +255,12 @@ void shutdownCars(void)
GfLogInfo("Delete cars in OsgMain\n");
}
if (carLights)
{
delete carLights;
carLights = NULL;
GfLogInfo("Delete carLights in OsgMain\n");
}
// Trace final mean F/s.
if (nFPSTotalSeconds > 0)
@ -280,9 +292,11 @@ int initCars(tSituation *s)
{
GfLogInfo("InitCars\n");
char buf[1024];
carLights = new SDCarLights;
cars = new SDCars;
carLights->loadStates();
cars->loadCars(s, scenery->getSpeedWay(), scenery->getSpeedWayLong());
render->addCars(cars->getCarsNode());
render->addCars(cars->getCarsNode(), carLights->getLightsRoot());
GfLogInfo("All cars loaded\n");
screens->InitCars(s);

View file

@ -75,6 +75,7 @@ public:
void * getScreens();
void * getRender();
void * getCarLights();
void * getCars();
void * getScenery();

View file

@ -76,6 +76,7 @@ SDRender::SDRender(void) :
m_RealRoot(NULL),
m_scene(NULL),
m_CarRoot(NULL),
m_CarLightsRoot(NULL),
skyGroup(NULL),
stateSet(NULL),
skySS(NULL),
@ -107,9 +108,9 @@ SDRender::SDRender(void) :
SDSunDeclination = 0.0f;
SDMoonDeclination = 0.0f;
SDMax_Visibility = 20000.0f;
SDMax_Visibility = 12000.0f;
SDVisibility = 20000.0f;
SDRain = 0;
SDRain = 0;
NStars = 0;
NPlanets = 0;
sol_angle = 0.0;
@ -123,6 +124,7 @@ SDRender::~SDRender(void)
{
m_scene->removeChildren(0, m_scene->getNumChildren());
m_CarRoot->removeChildren(0, m_CarRoot->getNumChildren());
m_CarLightsRoot->removeChildren(0, m_CarLightsRoot->getNumChildren());
skyGroup->removeChildren(0, skyGroup->getNumChildren());
m_RealRoot->removeChildren(0, m_RealRoot->getNumChildren());
stateSet->getTextureAttributeList().clear();
@ -130,6 +132,7 @@ SDRender::~SDRender(void)
m_scene = NULL;
m_CarRoot = NULL;
m_CarLightsRoot = NULL;
skyGroup = NULL;
m_RealRoot = NULL;
}
@ -259,7 +262,7 @@ void SDRender::Init(tTrack *track)
GfLogInfo("Graphic options : Shadow Type : %u\n", ShadowIndex);
GfLogInfo("Graphic options : Shadow Texture Size : %u\n", ShadowTexSize);
GfLogInfo("Graphic options : Shadow Quality : %u\n", QualityIndex);
GfLogInfo("Graphic options : Shader Quality : %u\n", carsShader);
GfLogInfo("Graphic options : Shader Quality : %u\n", carsShader);
NStars = NMaxStars;
if (AStarsData)
@ -282,6 +285,7 @@ void SDRender::Init(tTrack *track)
GfLogInfo(" Planets : %d\n", NPlanets);
const int timeOfDay = (int)SDTrack->local.timeofday;
//SDRain = (unsigned int)SDTrack->local.rain;
const double domeSizeRatio = SDSkyDomeDistance / 80000.0;
GfLogInfo(" domeSizeRation : %f\n", domeSizeRatio);
@ -360,6 +364,7 @@ void SDRender::Init(tTrack *track)
osg::ref_ptr<osgShadow::ShadowMap> vdsm = new osgShadow::ShadowMap;
m_scene = new osg::Group;
m_CarRoot = new osg::Group;
m_CarLightsRoot = new osg::Group;
m_RealRoot = new osg::Group;
shadowRoot = new osgShadow::ShadowedScene;
@ -373,9 +378,11 @@ void SDRender::Init(tTrack *track)
osg::ref_ptr<osg::Group> scene = new osg::Group;
osg::ref_ptr<osg::Group> background = new osg::Group;
osg::ref_ptr<osg::Group> cargroup = new osg::Group;
osg::ref_ptr<osg::Group> lights = new osg::Group;
scene->addChild(scenery->getScene());
cargroup->addChild(m_CarRoot.get());
lights->addChild(m_CarLightsRoot.get());
background->addChild(scenery->getBackground());
if(ShadowIndex > 0)
@ -387,16 +394,19 @@ void SDRender::Init(tTrack *track)
case 1:
scene->setNodeMask(~NODE_MASK_SHADOW_CAST);
background->setNodeMask(~(NODE_MASK_SHADOW_RECV | NODE_MASK_SHADOW_CAST));
lights->setNodeMask(~(NODE_MASK_SHADOW_RECV | NODE_MASK_SHADOW_CAST));
cargroup->setNodeMask(~NODE_MASK_SHADOW_RECV);
break;
case 2:
scene->setNodeMask(~NODE_MASK_SHADOW_CAST);
background->setNodeMask(~(NODE_MASK_SHADOW_RECV | NODE_MASK_SHADOW_CAST));
lights->setNodeMask(~(NODE_MASK_SHADOW_RECV | NODE_MASK_SHADOW_CAST));
cargroup->setNodeMask(NODE_MASK_ALL);
break;
case 3:
scene->setNodeMask(NODE_MASK_ALL);
background->setNodeMask(~(NODE_MASK_SHADOW_RECV | NODE_MASK_SHADOW_CAST));
lights->setNodeMask(~(NODE_MASK_SHADOW_RECV | NODE_MASK_SHADOW_CAST));
cargroup->setNodeMask(NODE_MASK_ALL);
break;
default:
@ -406,6 +416,7 @@ void SDRender::Init(tTrack *track)
m_scene->addChild(cargroup.get());
m_scene->addChild(scene.get());
m_scene->addChild(lights.get());
m_scene->addChild(background.get());
sceneGroup->addChild(m_scene.get());
@ -573,15 +584,17 @@ void SDRender::ShadowedScene()
m_RealRoot->addChild(thesky->getCloudRoot());
}
void SDRender::addCars(osg::Node* cars)
void SDRender::addCars(osg::Node* cars, osg::Node* carLights)
{
m_CarRoot->addChild(cars);
m_CarLightsRoot->addChild(carLights);
osgUtil::Optimizer optimizer;
optimizer.optimize(m_CarRoot.get());
optimizer.optimize(m_CarLightsRoot.get());
optimizer.optimize(m_scene.get());
if ((ShadowIndex > 0) & (SDVisibility > 4000))
if ((ShadowIndex > 0) & (SDVisibility > 4000) & (SDRain < 1))
ShadowedScene();
}
@ -856,7 +869,7 @@ void SDRender::weather(void)
cloudsTextureIndex2 = SDTrack->local.clouds2;
cloudsTextureIndex3 = SDTrack->local.clouds3;
switch (SDTrack->local.rain)
switch (SDTrack->local.rain)
{
case TR_RAIN_NONE:
SDVisibility = SDTrack->local.visibility;
@ -896,6 +909,7 @@ void SDRender::weather(void)
else if (SDNbCloudLayers == 1 && cloudsTextureIndex > 0)
{
SDCloudLayer *layer = new SDCloudLayer(datapath);
switch (cloudsTextureIndex)
{
case 0:

View file

@ -37,6 +37,7 @@ private:
osg::ref_ptr<osg::Group> m_RealRoot;
osg::ref_ptr<osg::Group> m_scene;
osg::ref_ptr<osg::Group> m_CarRoot;
osg::ref_ptr<osg::Group> m_CarLightsRoot;
osg::ref_ptr<osg::Group> skyGroup;
osg::ref_ptr<osg::StateSet> stateSet;
@ -78,7 +79,7 @@ private:
float SDMoonDeclination;
float SDMax_Visibility;
double SDVisibility;
unsigned int SDRain;
unsigned int SDRain;
unsigned ShadowIndex;
unsigned TexSizeIndex;
unsigned QualityIndex;
@ -105,7 +106,7 @@ public:
osg::Vec4f getSceneColor(void);
void UpdateTime(tSituation *s);
void UpdateLight(void);
void addCars(osg::Node* cars);
void addCars(osg::Node* cars, osg::Node* carLights);
void UpdateFogColor(double angle);
void UpdateSky(double currentTime, double accelTime, double X, double Y);
void ShadowedScene(void);
@ -117,6 +118,7 @@ public:
osg::ref_ptr<osg::Group> getRoot() { return m_RealRoot.get(); }
osg::ref_ptr<osg::Group> getSceneRoot() { return m_scene.get(); }
osg::ref_ptr<osg::Group> getCarRoot() { return m_CarRoot.get(); }
osg::ref_ptr<osg::Group> getCarLightsRoot() { return m_CarLightsRoot.get(); }
osg::Vec3f getFogColor() { return FogColor; }
};

View file

@ -0,0 +1,112 @@
/***************************************************************************
file : OsgLightTransform.cpp
created : Tue Mar 31 20:41:16 CEST 2020
......... : ...2020 Ivan Mahonin
email : bh@icystar.com
version : $Id$
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <osg/CullStack>
#include "OsgLightTransform.h"
static const double minScale = 1e-6;
SDLightTransform::SDLightTransform():
exponent(1)
{
}
SDLightTransform::SDLightTransform(const SDLightTransform &pat, const osg::CopyOp &copyop):
osg::Transform(pat, copyop),
position(pat.position),
matrix(pat.matrix),
appliedMatrix(pat.matrix),
exponent(pat.exponent)
{
}
bool SDLightTransform::computeLocalToWorldMatrix(osg::Matrix &matrix, osg::NodeVisitor *nv) const
{
if (_referenceFrame == osg::Transform::RELATIVE_RF)
matrix.preMult(appliedMatrix);
else
matrix = appliedMatrix;
return true;
}
bool SDLightTransform::computeWorldToLocalMatrix(osg::Matrix &matrix, osg::NodeVisitor *nv) const
{
osg::Matrix m;
m.invert(appliedMatrix);
if (_referenceFrame == osg::Transform::RELATIVE_RF)
matrix.postMult(m);
else
matrix = m;
return true;
}
void SDLightTransform::accept(osg::NodeVisitor &nv)
{
if (nv.validNodeMask(*this))
{
if (nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR)
{
if (osg::CullStack* cs = dynamic_cast<osg::CullStack*>(&nv))
{
osg::Vec3d pos = cs->getEyeLocal() - position;
pos.normalize();
double scale = pos*normal;
if (scale <= minScale)
{
appliedMatrix = matrix
* osg::Matrix::scale(minScale, minScale, minScale)
* osg::Matrix::translate(position);
}
else
{
const double *m = cs->getModelViewMatrix()->ptr();
scale = pow(scale, -fabs(exponent));
osg::Vec3d x(m[0], m[1], m[2]);
osg::Vec3d y(m[4], m[5], m[6]);
osg::Vec3d z(m[8], m[9], m[10]);
x.normalize();
y.normalize();
z.normalize();
x *= scale;
y *= scale;
z *= scale;
osg::Matrix rot(
x.x(), x.y(), x.z(), 0,
y.x(), y.y(), y.z(), 0,
z.x(), z.y(), z.z(), 0,
0, 0, 0, 1 );
osg::Matrix invRot;
invRot.invert_4x3(rot);
appliedMatrix = matrix * invRot * osg::Matrix::translate(position);
}
}
}
Transform::accept(nv);
}
}

View file

@ -0,0 +1,66 @@
/***************************************************************************
file : OsgLightTransform.h
created : Tue Mar 31 19:53:56 CEST 2020
......... : ...2020 Ivan Mahonin
email : bh@icystar.com
version : $Id$
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef _OSGLIGHTTRANSFORM_H_
#define _OSGLIGHTTRANSFORM_H_
#include <osg/Transform>
class SDLightTransform: public osg::Transform
{
protected:
osg::Vec3d position;
osg::Vec3d normal;
osg::Matrix matrix;
osg::Matrix appliedMatrix;
double exponent;
public :
SDLightTransform();
SDLightTransform(const SDLightTransform &pat, const osg::CopyOp &copyop = osg::CopyOp::SHALLOW_COPY);
protected :
virtual ~SDLightTransform() {}
public :
virtual osg::Object* cloneType() const { return new SDLightTransform(); }
virtual osg::Object* clone(const osg::CopyOp &copyop) const { return new SDLightTransform(*this, copyop); }
virtual bool isSameKindAs(const osg::Object *obj) const { return dynamic_cast<const SDLightTransform*>(obj)!=NULL; }
virtual const char* className() const { return "SDLightTransform"; }
virtual const char* libraryName() const { return "SD"; }
virtual void accept(osg::NodeVisitor& nv);
inline void setPosition(const osg::Vec3d &pos) { position = pos; }
inline const osg::Vec3d& getPosition() const { return position; }
inline void setNormal(const osg::Vec3d &n) { normal = n; normal.normalize(); }
inline const osg::Vec3d& getNormal() const { return position; }
inline void setMatrix(const osg::Matrix &m) { matrix = m; }
inline const osg::Matrix& getMatrix() const { return matrix; }
inline void setExponent(double e) { exponent = e; }
inline double getExponent() const { return exponent; }
virtual bool computeLocalToWorldMatrix(osg::Matrix &matrix, osg::NodeVisitor *nv) const;
virtual bool computeWorldToLocalMatrix(osg::Matrix &matrix, osg::NodeVisitor *nv) const;
};
#endif