void VertexCoordRemapper::Tree::GetInputCoordinates(const unsigned int node_num,
                                             double coords[2][2][2])
{
    // find the coordinates of each point at the vertices in the original image.
    // this is used to look up the remapped coordinates and provide texture
    // coordinates.
    // it halves in size several times depending on depth.
    unsigned int x, y, row_size, depth;
    GetPosition(node_num, x, y, row_size, depth);
    // now we can locate the upper right corner
    double row_spacing = 1.0 / (double) row_size;
    coords[0][0][0] = row_spacing * (double) x;
    coords[0][0][1] = row_spacing * (double) y;
    // the extent is dependent on the direction of the subdivisions.
    // at least one direction has an extent of row_spacing. It can double up
    // if the parent did not subdivide in a direction, recursively up the tree.
    bool scale_x = false;
    double opp = 1.0;
    if (node_num != 0)
    {    
      unsigned int parent_id = GetParentId(x, y, row_size, depth);
      if (!(nodes[parent_id].flags & split_flag_x))
      {
          while (!(nodes[parent_id].flags & split_flag_x))
          {
              parent_id = GetParentId(parent_id);
              opp *= 2.0;
          }
          scale_x = true;
      } else {
          while (!(nodes[parent_id].flags & split_flag_y))
          {
              parent_id = GetParentId(parent_id);
              opp *= 2.0;
          }
      }
    }
    opp *= row_spacing;
    coords[1][0][0] = coords[0][0][0] + (scale_x ? opp : row_spacing);
    coords[1][0][1] = coords[0][0][1];
    coords[0][1][0] = coords[0][0][0];
    coords[0][1][1] = coords[0][0][1] + (scale_x ? row_spacing : opp);
    coords[1][1][0] = coords[1][0][0];
    coords[1][1][1] = coords[0][1][1];
    // now we transform the results so that we map to the cropped region instead
    // of the whole image.
    for (unsigned int i = 0; i < 2; i++)
    {
        for (unsigned int j = 0; j < 2; j++)
        {
            coords[i][j][0] = coords[i][j][0] * x_crop_scale + x_crop_offs;
            coords[i][j][1] = coords[i][j][1] * y_crop_scale + y_crop_offs;
        }
    }
}
Exemplo n.º 2
0
wxTreeItemId  
BrushSelector::GetParentId( Ogre::String &catalog, CatalogMap &map )
{
	// 如果送入的相对路径为空,说明这个纹理放在资源目录的根目录下
	if ( catalog == "" )
		// 所以,它的节点应该被建在根目录下
		return mBrushesTree->GetRootItem();
	else
	{
		// 否则,先试图找它的上一级目录,如果有的话(说明这个目录在树中已经建好,可能是因为有同个目录下的纹理
		// 被处理过了),就返回这个目录
		CatalogMap::iterator i = map.find(catalog);

		if ( i != map.end() )
			return i->second;
		// 如果没有,就得递归往上找,并建树
		else
		{
			Ogre::String path, baseName;
			Ogre::StringUtil::splitFilename(catalog, baseName, path);
			if (!path.empty() && path[path.length()-1] == '/')
				path.erase(path.length() - 1);

			wxTreeItemId id = mBrushesTree->AppendItem( GetParentId(path, map), wxT(baseName) );

			map.insert( CatalogMap::value_type( catalog, id ) );

			mCatalogMap.insert(CatalogMap::value_type( baseName, id ));

			return id;
		}
	}
}
Exemplo n.º 3
0
int TagEntry::Update(wxSQLite3Statement& updatePerepareStmnt)
{
    // If this node is a dummy, (IsOk() == false) we dont update it to database
    if( !IsOk() )
        return TagOk;

    try
    {
        // see TagsDatabase::GetUpdateOneStatement() function for the order of binding
        updatePerepareStmnt.Bind(1, GetParentId());
        updatePerepareStmnt.Bind(2, GetName());
        updatePerepareStmnt.Bind(3, GetFile());
        updatePerepareStmnt.Bind(4, GetLine());
        updatePerepareStmnt.Bind(5, GetAccess());
        updatePerepareStmnt.Bind(6, GetPattern());
        updatePerepareStmnt.Bind(7, GetParent());
        updatePerepareStmnt.Bind(8, GetInherits());
        updatePerepareStmnt.Bind(9, GetTyperef());
        updatePerepareStmnt.Bind(10, GetScope());
        updatePerepareStmnt.Bind(11, GetKind());
        updatePerepareStmnt.Bind(12, GetSignature());
        updatePerepareStmnt.Bind(13, GetPath());
        updatePerepareStmnt.ExecuteUpdate();
        updatePerepareStmnt.Reset();
    }
    catch(wxSQLite3Exception& exc)
    {
        wxLogMessage(exc.GetMessage());
        return TagError;
    }
    return TagOk;
}
Exemplo n.º 4
0
int TagEntry::Store(wxSQLite3Statement& insertPerepareStmnt)
{
    // If this node is a dummy, (IsOk() == false) we dont insert it to database
    if( !IsOk() )
        return TagOk;

    try
    {
        // see TagsDatabase::GetInsertOneStatement() for the order of binding
        insertPerepareStmnt.Bind(1, GetParentId());
        insertPerepareStmnt.Bind(2, GetName());
        insertPerepareStmnt.Bind(3, GetFile());
        insertPerepareStmnt.Bind(4, GetLine());
        insertPerepareStmnt.Bind(5, GetKind());
        insertPerepareStmnt.Bind(6, GetAccess());
        insertPerepareStmnt.Bind(7, GetSignature());
        insertPerepareStmnt.Bind(8, GetPattern());
        insertPerepareStmnt.Bind(9, GetParent());
        insertPerepareStmnt.Bind(10, GetInherits());
        insertPerepareStmnt.Bind(11, GetPath());
        insertPerepareStmnt.Bind(12, GetTyperef());
        insertPerepareStmnt.Bind(13, GetScope());
        insertPerepareStmnt.ExecuteUpdate();
        insertPerepareStmnt.Reset();

    }
    catch(wxSQLite3Exception& exc)
    {
        if(exc.ErrorCodeAsString(exc.GetErrorCode()) == wxT("SQLITE_CONSTRAINT"))
            return TagExist;
        wxLogMessage(exc.GetMessage());
        return TagError;
    }
    return TagOk;
}
unsigned int VertexCoordRemapper::Tree::GetParentId(const unsigned int nodenum)
{
    // get the parent id of a node specifed by its index.
    unsigned int x, y, row_size, depth;
    GetPosition(nodenum, x, y, row_size, depth);
    return GetParentId(x, y, row_size, depth);
}
//---------------------------------------------
CWeapon* CLaser::GetWeapon() const
{
	IItem* pParentItem = m_pItemSystem->GetItem(GetParentId());
	if(pParentItem == NULL)
		return 0;
	CWeapon* pParentWeapon = static_cast<CWeapon*>(pParentItem->GetIWeapon());
	return pParentWeapon;
}
Exemplo n.º 7
0
//-------------------------------------------------------------------------
void CLam::ActivateLight(bool activate, bool aiRequest /* = false */)
{
    //GameWarning("CLam::ActivateLight(%i)", activate);

    CItem  *pParent = NULL;
    EntityId ownerId = 0;

    if (IItem *pOwnerItem = m_pItemSystem->GetItem(GetParentId()))
    {
        pParent = (CItem *)pOwnerItem;
        IWeapon *pWeapon = pOwnerItem->GetIWeapon();
        if(pWeapon)
            ownerId = pOwnerItem->GetOwnerId();
    }
    else
    {
        pParent = this;
        ownerId = GetOwnerId();
    }

    IActor *pOwnerActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(ownerId);
    if (activate && !pOwnerActor)
        return;

    //Special FP stuff
    if(pOwnerActor && pOwnerActor->IsPlayer() && !m_lamparams.isFlashLight)
        return;

    //For AI must be deactivated by default (if they don't request)
    if(activate && !m_lightWasOn && !aiRequest && !pOwnerActor->IsPlayer())
        return;

    m_lightActivated = activate;

    //Activate or deactivate effect
    if (!m_lightActivated)
    {
        AttachLAMLight(false, pParent, eIGS_FirstPerson);
        AttachLAMLight(false, pParent, eIGS_ThirdPerson);

        //GameWarning("Global light count = %d", s_lightCount);
    }
    else
    {
        uint8 id = pOwnerActor->IsThirdPerson() ? 1 : 0;
        if (m_lightID[id] == 0)
        {
            AttachLAMLight(true, pParent, id?eIGS_ThirdPerson:eIGS_FirstPerson);
        }
    }

    if (m_laserActivated || m_lightActivated)
        GetGameObject()->EnablePostUpdates(this);
    if (!m_laserActivated && !m_lightActivated)
        GetGameObject()->DisablePostUpdates(this);

}
Exemplo n.º 8
0
CWeapon* CFlashLight::GetWeapon() const
{
	IItem* pParentItem = m_pItemSystem->GetItem(GetParentId());

	if (pParentItem == NULL)
	{
		return 0;
	}

	CWeapon* pParentWeapon = static_cast<CWeapon*>(pParentItem->GetIWeapon());
	return pParentWeapon;
}
Exemplo n.º 9
0
//---------------------------------------------------------------------------
void CLam::PostUpdate(float frameTime)
{
    if (IItem *pOwnerItem = m_pItemSystem->GetItem(GetParentId()))
    {
        CItem* pParentItem = (CItem *)pOwnerItem;
        if(!pParentItem->IsOwnerFP() && pParentItem->IsSelected())
            UpdateTPLaser(frameTime,pParentItem);
        else if(pParentItem->IsOwnerFP())
            UpdateFPLaser(frameTime,pParentItem);
    }

}
Exemplo n.º 10
0
CItem::ePhysicalization CAccessory::FindPhysicalisationType( bool enable, bool rigid )
{
    const bool isMounted = (GetParentId() != 0);

    ePhysicalization physType = eIPhys_NotPhysicalized;

    if(enable && !isMounted)
        {
            physType = rigid ? eIPhys_PhysicalizedRigid : eIPhys_PhysicalizedStatic;
        }

    return physType;
}
Exemplo n.º 11
0
//-------------------------------------------------------------------------
void CLam::OnAttach(bool attach)
{
    CAccessory::OnAttach(attach);

    if(CItem* pItem = static_cast<CItem*>(m_pItemSystem->GetItem(GetParentId())))
    {
        if(pItem->GetOwnerActor() && pItem->GetOwnerActor()->IsPlayer())
        {
            ActivateLaser(attach);
            ActivateLight(attach);
        }
    }
}
Exemplo n.º 12
0
void CAccessory::Physicalize( bool enable, bool rigid )
{
    const bool isMounted = (GetParentId() != 0);

    int profile = eIPhys_NotPhysicalized;
    if (enable && !isMounted)
        {
            profile = rigid ? eIPhys_PhysicalizedRigid : eIPhys_PhysicalizedStatic;
        }

    if (IsServer())
        {
            GetGameObject()->SetAspectProfile(eEA_Physics, profile);
        }

    m_deferPhysicalization = eIPhys_Max;
}
Exemplo n.º 13
0
//------------------------------------------------------------------
void CLam::UpdateAILightAndLaser(const Vec3& pos, const Vec3& dir, float lightRange, float fov, float laserRange)
{
    if (!gEnv->pAISystem)
        return;

    EntityId userId = 0;
    if (IItem *pOwnerItem = m_pItemSystem->GetItem(GetParentId()))
    {
        CItem* pParentItem = (CItem *)pOwnerItem;
        userId = pParentItem->GetOwnerId();
    }

    if (lightRange > 0.0001f)
    {
        gEnv->pAISystem->DynSpotLightEvent(pos, dir, lightRange, DEG2RAD(fov)/2, AILE_FLASH_LIGHT, userId, 1.0f);
        gEnv->pAISystem->DynOmniLightEvent(pos - dir*0.5f, 1.5f, AILE_FLASH_LIGHT, userId, 2.0f);
    }

    // [Mikko] 4.10.2007 Removed as per design request.
    /*	if (laserRange > 0.0001f)
    	{
    		gEnv->pAISystem->DynSpotLightEvent(pos, dir, max(0.0f, laserRange - 0.1f), DEG2RAD(0.25f), AILE_LASER, pUserAI, 2.0f);
    	}*/
}
Exemplo n.º 14
0
//-------------------------------------------------------------------------
void CLam::ActivateLaser(bool activate, bool aiRequest /* = false */)
{
    if (m_laserActivated == activate)
        return;

    CItem  *pParent = NULL;
    EntityId ownerId = 0;
    bool ok = false;

    if (IItem *pOwnerItem = m_pItemSystem->GetItem(GetParentId()))
    {
        pParent = (CItem *)pOwnerItem;
        IWeapon *pWeapon = pOwnerItem->GetIWeapon();
        if(pWeapon)
            ownerId = pOwnerItem->GetOwnerId();

        ok = true;
    }
    else
    {
        pParent = this;
        ownerId = GetOwnerId();
    }

    IActor *pOwnerActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(ownerId);
    if(!pOwnerActor)
        return;

    if(activate && !aiRequest && !pOwnerActor->IsPlayer())
        return;

    //Special FP stuff
    if(pOwnerActor->IsPlayer() && !m_lamparams.isLaser)
        return;

    m_laserActivated = activate;

    //Activate or deactivate effect??
    if (!m_laserActivated)
    {
        AttachLAMLaser(false, eIGS_FirstPerson);
        AttachLAMLaser(false, eIGS_ThirdPerson);
    }
    else
    {
        bool tp = pOwnerActor->IsThirdPerson();
        if(!tp && ok)
        {
            SAccessoryParams *params = pParent->GetAccessoryParams(GetEntity()->GetClass()->GetName());
            if (!params)
                return;

            m_laserHelperFP.clear();
            m_laserHelperFP = params->attach_helper.c_str();
            m_laserHelperFP.replace("_LAM","");
        }
        AttachLAMLaser(true, tp?eIGS_ThirdPerson:eIGS_FirstPerson);
    }

    if (m_laserActivated || m_lightActivated)
        GetGameObject()->EnablePostUpdates(this);
    if (!m_laserActivated && !m_lightActivated)
        GetGameObject()->DisablePostUpdates(this);
}
Exemplo n.º 15
0
//------------------------------------------------------------------------
bool CItem::SetGeometry(int slot, const ItemString& name, const ItemString& material, bool useParentMaterial, const Vec3& poffset, const Ang3& aoffset, float scale, bool forceReload)
{
    assert(slot >= 0 && slot < eIGS_Last);

    bool changedfp=false;
    switch(slot)
        {
        case eIGS_Owner:
            break;
        case eIGS_FirstPerson:
        case eIGS_ThirdPerson:
        default:
        {
            if (name.empty() || forceReload)
                {
                    GetEntity()->FreeSlot(slot);
#ifndef ITEM_USE_SHAREDSTRING
                    m_geometry[slot].resize(0);
#else
                    m_geometry[slot].reset();
#endif
                }

            DestroyAttachmentHelpers(slot);

            if (!name.empty())
                {
                    if (m_geometry[slot] != name)
                        {
                            const char* ext = PathUtil::GetExt(name.c_str());
                            if ((stricmp(ext, "chr") == 0) || (stricmp(ext, "cdf") == 0) || (stricmp(ext, "cga") == 0) )
                                GetEntity()->LoadCharacter(slot, name.c_str(), 0);
                            else
                                GetEntity()->LoadGeometry(slot, name.c_str(), 0, 0);

                            changedfp=slot==eIGS_FirstPerson;
                        }

                    CreateAttachmentHelpers(slot);
                }

            /*			if (slot == eIGS_FirstPerson)
            			{
            				ICharacterInstance *pCharacter = GetEntity()->GetCharacter(eIGS_FirstPerson);
            				if (pCharacter)
            				{
            					pCharacter->SetFlags(pCharacter->GetFlags()&(~CS_FLAG_UPDATE));
            				}
            			}
                  else */if (slot == eIGS_Destroyed)
                DrawSlot(eIGS_Destroyed, false);
        }
        break;
        }

    Matrix34 slotTM;
    slotTM = Matrix34::CreateRotationXYZ(aoffset);
    slotTM.ScaleColumn(Vec3(scale, scale, scale));
    slotTM.SetTranslation(poffset);
    GetEntity()->SetSlotLocalTM(slot, slotTM);

    if (changedfp && m_stats.mounted)
        {
            if (m_sharedparams->pMountParams && !m_sharedparams->pMountParams->pivot.empty())
                {
                    Matrix34 tm=GetEntity()->GetSlotLocalTM(eIGS_FirstPerson, false);
                    Vec3 pivot = GetSlotHelperPos(eIGS_FirstPerson, m_sharedparams->pMountParams->pivot.c_str(), false);
                    tm.AddTranslation(pivot);

                    GetEntity()->SetSlotLocalTM(eIGS_FirstPerson, tm);
                }

            GetEntity()->InvalidateTM();
        }

    m_geometry[slot] = name ? name : ItemString();

    ReAttachAccessories();

    IEntity* pParentEntity = gEnv->pEntitySystem->GetEntity(GetParentId());
    IMaterial* pOverrideMaterial = 0;
    if (!material.empty())
        {
            pOverrideMaterial = gEnv->p3DEngine->GetMaterialManager()->LoadMaterial(material.c_str());
        }
    else if (useParentMaterial && pParentEntity)
        {
            ICharacterInstance* pParentCharacter = pParentEntity->GetCharacter(slot);
            IEntityRenderProxy* pParentRenderProxy = static_cast<IEntityRenderProxy*>(pParentEntity->GetProxy(ENTITY_PROXY_RENDER));
            if (pParentCharacter)
                pOverrideMaterial = pParentCharacter->GetIMaterial();
            else if (pParentRenderProxy)
                pOverrideMaterial = pParentRenderProxy->GetSlotMaterial(slot);
        }
    if (pOverrideMaterial)
        {
            ICharacterInstance* pCharacter = GetEntity()->GetCharacter(slot);
            IEntityRenderProxy* pRenderProxy = static_cast<IEntityRenderProxy*>(GetEntity()->GetProxy(ENTITY_PROXY_RENDER));
            OverrideAttachmentMaterial(pOverrideMaterial, this, slot);
            if (pCharacter)
                pCharacter->SetIMaterial_Instance(pOverrideMaterial);
            else if (pRenderProxy)
                pRenderProxy->SetSlotMaterial(slot, pOverrideMaterial);
        }

    if(slot == eIGS_FirstPerson && IsSelected())
        {
            CActor* pOwnerActor = GetOwnerActor();
            IActionController *pActionController = GetActionController();
            if(pActionController && pOwnerActor && pOwnerActor->IsClient())
                {
                    UpdateScopeContexts(pActionController);
                }
        }

    return true;
}
Exemplo n.º 16
0
void
BrushSelector::ReloadTextureList(void)
{
	CatalogMap catalogMap;
	mCatalogMap.clear();

    if (!Ogre::ResourceGroupManager::getSingletonPtr())
        return;

    mBrushesTree->Freeze();

    mBrushesTree->DeleteAllItems();

	wxTreeItemId rootId = mBrushesTree->AddRoot(/*_("Brushes")*/wxT("画刷列表"));
 
    // 重新解析定义文件
    GetSceneManipulator()->reloadPaintInfo();

    const Fairy::TerrainPaintInfoContainer *paintInfoContainer = GetSceneManipulator()->getTerrainPaintInfoContainer();

    assert (paintInfoContainer);

    const Fairy::TextureInfoMap &textureInfoMap = paintInfoContainer->getTextureInfoMap();

	OwnerTexs ownerTextures;

	Fairy::TextureInfoMap::const_iterator it = textureInfoMap.begin();	

    // 遍历画刷数组
    while ( it != textureInfoMap.end() )
    {
        const Fairy::TextureInfos &textureInfos = it->second;
        
        // 遍历该画刷下的所有纹理
        for ( size_t i=0; i<textureInfos.size(); ++i )
        {
            // 取出所属的大纹理的名称
            Ogre::String ownerTexName = textureInfos[i].ownerTextureName;

			// 记录大纹理的名称
			ownerTextures.insert(OwnerTexs::value_type(ownerTexName, ownerTexName));

            // 如果该纹理名称中包含了/,说明它是在一个文件夹中的
            size_t pos = ownerTexName.find_last_of('/');

            // 在文件夹中
            if (pos != Ogre::String::npos)
            {
                // 先去除纹理文件名,剩下路径名
                ownerTexName.erase(pos+1);
                // 加上画刷的名称
                ownerTexName.append(textureInfos[i].brushName);
                wxTreeItemId id = mBrushesTree->AppendItem( GetParentId(ownerTexName, catalogMap), wxT(textureInfos[i].textureName) );
				
				mCatalogMap.insert(CatalogMap::value_type( textureInfos[i].textureName, id ));
            }
            else
            {
                Ogre::String brushName = textureInfos[i].brushName;
                // 如果是在根目录下,就直接用画刷名称来作为路径名
                wxTreeItemId id = mBrushesTree->AppendItem( GetParentId(brushName, catalogMap), wxT(textureInfos[i].textureName) );
				mCatalogMap.insert(CatalogMap::value_type( textureInfos[i].textureName, id ));
			}				
        }
        ++it;
    }

	wxString lostTexNames = wxEmptyString;
	for (OwnerTexs::iterator ownerIt = ownerTextures.begin(); ownerIt != ownerTextures.end(); ++ownerIt)
	{
		Ogre::String texName = ownerIt->first;

		Ogre::FileInfoListPtr fileInfoList =
			Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo("Brushes",texName);
		
		Ogre::FileInfoList::const_iterator itBegin = fileInfoList->begin();
		Ogre::FileInfoList::const_iterator itEnd = fileInfoList->end(); 
		if (itBegin == itEnd)
		{
			lostTexNames+=wxT("\n");
			lostTexNames+=texName.c_str();
			 continue;
		}

		Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().getByName(texName);

		if (!texture.isNull())
		{
			Ogre::TextureManager::getSingleton().remove(texName);
			Ogre::Image image;
			image.load(texName, Fairy::BRUSH_RESOURCE_GROUP_NAME);
			texture = Ogre::TextureManager::getSingleton()
				.loadImage(texName, Fairy::BRUSH_RESOURCE_GROUP_NAME, image);
		}
	}	

	if (!lostTexNames.empty())
	{
		wxMessageBox(wxT("以下贴图无法找到:")+lostTexNames);
	}

    mBrushesTree->Thaw();
}
Exemplo n.º 17
0
//------------------------------------------------------------------
void CLam::UpdateTPLaser(float frameTime, CItem* parent)
{
    FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);

    const int frameId = gEnv->pRenderer->GetFrameID();

    if (s_lastUpdateFrameId != frameId)
    {
        // Check how many LAMs to update this frame.
        float dt = frameTime; // + s_laserUpdateTimeError;

        const int n = s_lasers.size();

        int nActive = 0;
        for (int i = 0; i < n; ++i)
        {
            if (!s_lasers[i]->IsLaserActivated() && !s_lasers[i]->IsLightActivated())
                continue;
            nActive++;
        }

        float updatedPerSecond = (nActive / LASER_UPDATE_TIME) + s_laserUpdateTimeError;
        int updateCount = (int)floorf(updatedPerSecond * dt);
        if(dt==0.0f)
            s_laserUpdateTimeError = 0.0f;
        else
            s_laserUpdateTimeError = updatedPerSecond - updateCount/dt;

        s_curLaser %= n;
        for (int i = 0, j = 0; i < n && j < updateCount ; ++i)
        {
            s_curLaser = (s_curLaser + 1) % n;
            if (!s_lasers[s_curLaser]->IsLaserActivated() && !s_lasers[s_curLaser]->IsLightActivated())
                continue;
            s_lasers[s_curLaser]->SetAllowUpdate();
            ++j;
        }

        s_lastUpdateFrameId = frameId;
    }

    IEntity* pRootEnt = GetEntity();
    if (!pRootEnt)
        return;

    IEntity *pLaserEntity = m_pEntitySystem->GetEntity(m_pLaserEntityId);
//	if(!pLaserEntity)
//		return;

    const CCamera& camera = gEnv->pRenderer->GetCamera();

    Vec3   lamPos = pRootEnt->GetWorldPos(); //pLaserEntity->GetParent()->GetWorldPos();
    Vec3   dir = pRootEnt->GetWorldRotation().GetColumn1(); //pLaserEntity->GetParent()->GetWorldRotation().GetColumn1();

    bool charNotVisible = false;

    float  dsg1Scale = 1.0f;

    //If character not visible, laser is not correctly updated
    if(parent)
    {
        if(CActor* pOwner = parent->GetOwnerActor())
        {
            ICharacterInstance* pCharacter = pOwner->GetEntity()->GetCharacter(0);
            if(pCharacter && !pCharacter->IsCharacterVisible())
                charNotVisible = true;
        }
        if(parent->GetEntity()->GetClass()==CItem::sDSG1Class)
            dsg1Scale = 3.0f;
    }

//	if (!pLaserEntity->GetParent())
//		return;

    Vec3 hitPos(0,0,0);
    float laserLength = 0.0f;

    // HACK??: Use player movement controller locations, or else the laser
    // pops all over the place when character out of the screen.
    CActor *pActor = parent->GetOwnerActor();
    if (pActor && (!pActor->IsPlayer() || charNotVisible))
    {
        if (IMovementController* pMC = pActor->GetMovementController())
        {
            SMovementState state;
            pMC->GetMovementState(state);
            if(!charNotVisible)
                lamPos = state.weaponPosition;
            else
            {
                float oldZPos = lamPos.z;
                lamPos = state.weaponPosition;
                if(m_lastZPos>0.0f)
                    lamPos.z = m_lastZPos; //Stabilize somehow z position (even if not accurate)
                else
                    lamPos.z = oldZPos;
            }
            const float angleMin = DEG2RAD(3.0f);
            const float angleMax = DEG2RAD(7.0f);
            const float thr = cosf(angleMax);
            float dot = dir.Dot(state.aimDirection);
            if (dot > thr)
            {
                float a = acos_tpl(dot);
                float u = 1.0f - clamp((a - angleMin) / (angleMax - angleMin), 0.0f, 1.0f);
                dir = dir + u * (state.aimDirection - dir);
                dir.Normalize();
            }
        }
    }

    if(!charNotVisible)
        m_lastZPos = lamPos.z;

    lamPos += (dir*0.10f);

    if (m_allowUpdate)
    {
        m_allowUpdate = false;

        IPhysicalEntity* pSkipEntity = NULL;
        if(parent->GetOwner())
            pSkipEntity = parent->GetOwner()->GetPhysics();

        const float range = m_lamparams.laser_range[eIGS_ThirdPerson]*dsg1Scale;

        // Use the same flags as the AI system uses for visbility.
        const int objects = ent_terrain|ent_static|ent_rigid|ent_sleeping_rigid|ent_independent; //ent_living;
        const int flags = (geom_colltype_ray << rwi_colltype_bit) | rwi_colltype_any | (10 & rwi_pierceability_mask) | (geom_colltype14 << rwi_colltype_bit);

        ray_hit hit;
        if (gEnv->pPhysicalWorld->RayWorldIntersection(lamPos, dir*range, objects, flags,
                &hit, 1, &pSkipEntity, pSkipEntity ? 1 : 0))
        {
            laserLength = hit.dist;
            m_lastLaserHitPt = hit.pt;
            m_lastLaserHitSolid = true;
        }
        else
        {
            m_lastLaserHitSolid = false;
            m_lastLaserHitPt = lamPos + dir * range;
            laserLength = range + 0.1f;
        }

        // Hit near plane
        if (dir.Dot(camera.GetViewdir()) < 0.0f)
        {
            Plane nearPlane;
            nearPlane.SetPlane(camera.GetViewdir(), camera.GetPosition());
            nearPlane.d -= camera.GetNearPlane()+0.15f;
            Ray ray(lamPos, dir);
            Vec3 out;
            m_lastLaserHitViewPlane = false;
            if (Intersect::Ray_Plane(ray, nearPlane, out))
            {
                float dist = Distance::Point_Point(lamPos, out);
                if (dist < laserLength)
                {
                    laserLength = dist;
                    m_lastLaserHitPt = out;
                    m_lastLaserHitSolid = true;
                    m_lastLaserHitViewPlane = true;
                }
            }
        }

        hitPos = m_lastLaserHitPt;
    }
    else
    {
        laserLength = Distance::Point_Point(m_lastLaserHitPt, lamPos);
        hitPos = lamPos + dir * laserLength;
    }

    if (m_smoothLaserLength < 0.0f)
        m_smoothLaserLength = laserLength;
    else
    {
        if (laserLength < m_smoothLaserLength)
            m_smoothLaserLength = laserLength;
        else
            m_smoothLaserLength += (laserLength - m_smoothLaserLength) * min(1.0f, 10.0f * frameTime);
    }

    float laserAIRange = 0.0f;
    if (m_laserActivated && pLaserEntity)
    {
        // Orient the laser towards the point point.
        Matrix34 parentTMInv;
        parentTMInv = pRootEnt->GetWorldTM().GetInverted();

        Vec3 localDir = parentTMInv.TransformPoint(hitPos);
        float finalLaserLen = localDir.NormalizeSafe();
        Matrix33 rot;
        rot.SetIdentity();
        rot.SetRotationVDir(localDir);
        pLaserEntity->SetLocalTM(rot);

        laserAIRange = finalLaserLen;

        const float assetLength = 2.0f;
        finalLaserLen = CLAMP(finalLaserLen,0.01f,m_lamparams.laser_max_len*dsg1Scale);
        float scale = finalLaserLen / assetLength;

        // Scale the laser based on the distance.
        if (m_laserEffectSlot >= 0)
        {
            Matrix33 scl;
            scl.SetIdentity();
            scl.SetScale(Vec3(1,scale,1));
            pLaserEntity->SetSlotLocalTM(m_laserEffectSlot, scl);
        }

        if (m_dotEffectSlot >= 0)
        {
            if (m_lastLaserHitSolid)
            {
                Matrix34 mt = Matrix34::CreateTranslationMat(Vec3(0,finalLaserLen,0));
                if(m_lastLaserHitViewPlane)
                    mt.Scale(Vec3(0.2f,0.2f,0.2f));
                pLaserEntity->SetSlotLocalTM(m_dotEffectSlot, mt);
            }
            else
            {
                Matrix34 scaleMatrix;
                scaleMatrix.SetIdentity();
                scaleMatrix.SetScale(Vec3(0.001f,0.001f,0.001f));
                pLaserEntity->SetSlotLocalTM(m_dotEffectSlot, scaleMatrix);
            }
        }
    }

    float lightAIRange = 0.0f;
    if (m_lightActivated)
    {
        float range = clamp(m_smoothLaserLength, 0.5f, m_lamparams.light_range[eIGS_ThirdPerson]);
        lightAIRange = range * 1.5f;

        if (m_lightID[eIGS_ThirdPerson] && m_smoothLaserLength > 0.0f)
        {
            CItem* pLightEffect = this;
            if (IItem *pOwnerItem = m_pItemSystem->GetItem(GetParentId()))
                pLightEffect = (CItem *)pOwnerItem;
            pLightEffect->SetLightRadius(range, m_lightID[eIGS_ThirdPerson]);
        }
    }


    if (laserAIRange > 0.0001f || lightAIRange > 0.0001f)
        UpdateAILightAndLaser(lamPos, dir, lightAIRange, m_lamparams.light_fov[eIGS_ThirdPerson], laserAIRange);

}