Page 1 of 1

doLightRecalc() need improve for spot and direct light

Posted: Mon Feb 16, 2015 11:59 am
by feelthat
ref. https://gist.github.com/patriciogonzale ... a542aabc63

//outer code here
camera = smgr->addCameraSceneNodeFPS(0, 100.0f, .02f, 0, 0, 0, true, 1.0f);
camera->setPosition(core::vector3df(0,0,110));
camera->setTarget(core::vector3df(0,0,110.5));
.
.
.
scnode = smgr->addLightSceneNode(0, core::vector3df(0,5,120), video::SColorf(1.0f, 1.0f, 1.0f, 1.0f), 100.0f, -1);
scnode->setRotation(core::vector3df(0,0,5));
.
.
.
spotLightData = scnode->getLightData();
spotLightData.Type = video::ELT_SPOT;
spotLightData.Direction = core::vector3df(0,0.2,1);
spotLightData.Falloff = 60.0f;
spotLightData.OuterCone = 20;
scnode->setLightData(spotLightData);
.
.
.
node = smgr->addAnimatedMeshSceneNode( mesh );
node->setPosition(core::vector3df(0,0,140));

/////
///////inner code here
/////////////void CLightSceneNode::doLightRecalc()
if ((LightData.Type == video::ELT_SPOT) || (LightData.Type == video::ELT_DIRECTIONAL))
{
LightData.Direction = core::vector3df(.0f,.0f,1.0f);
getAbsoluteTransformation().rotateVect(LightData.Direction);
LightData.Direction.normalize();
}

/////////Spot light test
//if do the 3 code lines then spotLightData.Direction = core::vector3df(0,0.2,1); setting is non useful
// light direction non use
LightData.Direction = core::vector3df(.0f,.0f,1.0f);
getAbsoluteTransformation().rotateVect(LightData.Direction);
LightData.Direction.normalize();

////
//if mark this one line
//LightData.Direction = core::vector3df(.0f,.0f,1.0f);
getAbsoluteTransformation().rotateVect(LightData.Direction);
LightData.Direction.normalize(); //then spot light on the mesh node will turn and turn again, never stop
//scnode->setRotation(core::vector3df(0,0,z)); //the z bigger the turn more faster

////////
the correct spot light need mark, test in OGLES1 OGLES2 all the same result~
//LightData.Direction = core::vector3df(.0f,.0f,1.0f);
//getAbsoluteTransformation().rotateVect(LightData.Direction);

and need do once only
getAbsoluteTransformation().rotateVect(LightData.Direction);

Re: doLightRecalc() need improve for spot and direct light

Posted: Mon Feb 16, 2015 1:47 pm
by CuteAlien
@feelthat: Can you please use a normal diff tool to create patches? On Windows there is WinDiff on Linux there is diff. If you work with Irrlicht-svn you can use svn diff to directly create a patch. Working with your own hand-written format makes it so much harder for us to read and understand your patches! (for example you leave out filename and line-number information)

edit: Also please post some examples if you run into bugs. I suspect you have an example already as you can see the problem. Otherwise we have to write them from scratch and hope we can see your problem at the end. And chances we find time for that are... some epsilon approaching zero.

Re: doLightRecalc() need improve for spot and direct light

Posted: Mon Feb 16, 2015 1:59 pm
by feelthat
//ok will be~
/whole example to test in OGLES2

void Mesh3DInitScene()
{
IAnimatedMesh* mesh;
IAnimatedMeshSceneNode* node;
scene::ISceneNodeAnimator* anim;
scene::ISceneManager* smgr = IrrlichtManager::GetIrrlichtManager()->GetScene();
IrrlichtDevice* device = IrrlichtManager::GetIrrlichtManager()->GetDevice();
video::IVideoDriver* driver = IrrlichtManager::GetIrrlichtManager()->GetDriver();

std::string load_zip;
std::string load_data;
std::string reload_path;
FileSystemZip* pfilesystem = NULL;
io::IReadFile* memfile = NULL;
byte* apk_buffer = NULL;
byte* buff_extract = NULL;
int size = 0;
int apk_size = 0;

if (!IrrlichtManager::GetIrrlichtManager()->GetDevice())
{
LogError("Error initializing Irrlicht");
return;
}

IrrlichtManager::GetIrrlichtManager()->GetDevice()->getTimer()->setTime(0);

//////////////////////////////////cam/////////////////////////////////////////////
ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 100.0f, .02f, 0, 0, 0, true, 1.0f);
//ICameraSceneNode* camera = smgr->addCameraSceneNode(0, core::vector3df(0,0,10));
camera->setPosition(core::vector3df(0,0,110));
camera->setTarget(core::vector3df(0,0,110.5));
//camera->setRotation(core::vector3df(0,0,0));
float fov = float(GetPrimaryGLX())/ float(GetPrimaryGLY());
camera->setAspectRatio(fov);
camera->setFOV((120 * M_PI / 360.0f));

//////////////////

SLight spotLightData;
ILightSceneNode* scnode = smgr->addLightSceneNode(0, core::vector3df(0,0,120), video::SColorf(1.0f, 1.0f, 1.0f, 1.0f), 100.0f, -1);

scnode->setRotation(core::vector3df(10,0,0)); //scnode->setLightData(spotLightData); will over this func

spotLightData = scnode->getLightData();

spotLightData.Type = video::ELT_SPOT;
spotLightData.Direction = core::vector3df(0,0.5,1);
spotLightData.Falloff = 60.0f;
spotLightData.OuterCone = 20;
scnode->setLightData(spotLightData);

//////////////////////////////mesh/////////////////////////////////////////////////
load_zip = (GetBaseAppPath() + "game/squirrel.zip").c_str();
load_data = "squirrel.x";
reload_path = (GetBaseAppPath() + "game/squirrel.x").c_str();

#ifdef ANDROID_NDK
apk_buffer = FileManager::GetFileManager()->Get(load_zip.c_str(), &apk_size, false, false);

if( apk_buffer )
{
pfilesystem = new FileSystemZip();
pfilesystem->Init_unzMemory(apk_buffer, apk_size);
buff_extract = pfilesystem->Get_unz(load_data, &size);

delete apk_buffer;
apk_buffer = NULL;
}
#else
pfilesystem = new FileSystemZip();
pfilesystem->Init_unz(load_zip.c_str());
buff_extract = pfilesystem->Get_unz(load_data.c_str(), &size);
#endif

memfile = device->getFileSystem()->createMemoryReadFile(buff_extract, size, reload_path.c_str(), true);

mesh = smgr->getMesh( memfile );
node = smgr->addAnimatedMeshSceneNode( mesh );

//delete buff_extract in drop() then goto ~CMemoryReadFile
memfile->drop();

if( pfilesystem )
{
delete pfilesystem;
pfilesystem = NULL;
}

//////////////////////////////texture/////////////////////////////////////////////////
node->setMaterialTexture( 0, driver->getTexture((GetBaseAppPath()+"game/squirrel_skin.jpg").c_str()) );
node->setMaterialFlag(EMF_LIGHTING, true);
node->setMaterialFlag(EMF_NORMALIZE_NORMALS, true);

node->setPosition(core::vector3df(0,0,140));
node->setScale(core::vector3df(4,4,4));
node->setRotation(core::vector3df(0,90,0));


#ifdef _IRR_COMPILE_WITH_GUI_
EventControlComponent* receiver = new EventControlComponent();
receiver->AddGuiButton();
device->setEventReceiver(receiver);
#endif
}


CuteAlien wrote:@feelthat: Can you please use a normal diff tool to create patches? On Windows there is WinDiff on Linux there is diff. If you work with Irrlicht-svn you can use svn diff to directly create a patch. Working with your own hand-written format makes it so much harder for us to read and understand your patches! (for example you leave out filename and line-number information)

edit: Also please post some examples if you run into bugs. I suspect you have an example already as you can see the problem. Otherwise we have to write them from scratch and hope we can see your problem at the end. And chances we find time for that are... some epsilon approaching zero.

Re: doLightRecalc() need improve for spot and direct light

Posted: Mon Feb 16, 2015 2:00 pm
by feelthat
//fixed way here

void CLightSceneNode::setLightData(const video::SLight& light)
{
LightData = light;

//ogles2 need cos(outer cone)
switch(SceneManager->getVideoDriver()->getDriverType())
{
//radians
case video::EDT_OGLES2:
LightData.OuterCone = (float)cos(light.OuterCone * 3.141615926 / 180.0f);
LightData.InnerCone = (float)cos(light.InnerCone * 3.141615926 / 180.0f);
break;

//degrees
default:
break;
}

LightData.Direction.normalize();

}

//add whole setRotation function
void CLightSceneNode::setRotation(const core::vector3df& rotation)
{
ISceneNode::RelativeRotation = rotation;
updateAbsolutePosition();

getAbsoluteTransformation().rotateVect(LightData.Direction);
LightData.Direction.normalize();
}

void CLightSceneNode::doLightRecalc()
{
/*if ((LightData.Type == video::ELT_SPOT) || (LightData.Type == video::ELT_DIRECTIONAL))
{
//LightData.Direction = core::vector3df(.0f,.0f,1.0f); //mark here by stone
//getAbsoluteTransformation().rotateVect(LightData.Direction); //mark here
LightData.Direction.normalize();
}*/

if ((LightData.Type == video::ELT_SPOT) || (LightData.Type == video::ELT_POINT))
{
const f32 r = LightData.Radius * LightData.Radius * 0.5f;
BBox.MaxEdge.set( r, r, r );
BBox.MinEdge.set( -r, -r, -r );
//setAutomaticCulling( scene::EAC_BOX );
setAutomaticCulling( scene::EAC_OFF );
LightData.Position = getAbsolutePosition();
}
if (LightData.Type == video::ELT_DIRECTIONAL)
{
BBox.reset( 0, 0, 0 );
setAutomaticCulling( scene::EAC_OFF );
}
}

Re: doLightRecalc() need improve for spot and direct light

Posted: Mon Feb 16, 2015 2:58 pm
by feelthat
//use way
SLight spotLightData;
ILightSceneNode* scnode = smgr->addLightSceneNode(0, core::vector3df(0,5,120), video::SColorf(1.0f, 1.0f, 1.0f, 1.0f), 100.0f, -1);


scnode->setRotation(core::vector3df(30,0,0));
spotLightData = scnode->getLightData();

spotLightData.Type = video::ELT_SPOT;

//if add this line will over cover setRotation(core::vector3df(30,0,0));
// scnode->setRotation or spotLightData.Direction select one to use
spotLightData.Direction = core::vector3df(0,1,1);

spotLightData.Falloff = 60.0f;
spotLightData.OuterCone = 20;

scnode->setLightData(spotLightData);