예제 #1
0
//------------------------------------------------------------------------
bool CProjectile::Init(IGameObject *pGameObject)
{
	SetGameObject(pGameObject);

	g_pGame->GetWeaponSystem()->AddProjectile(GetEntity(), this);

	if (!GetGameObject()->CaptureProfileManager(this))
		return false;

	m_pAmmoParams = g_pGame->GetWeaponSystem()->GetAmmoParams(GetEntity()->GetClass());

	if (0 == (GetEntity()->GetFlags() & (ENTITY_FLAG_CLIENT_ONLY | ENTITY_FLAG_SERVER_ONLY)))
		if (!m_pAmmoParams->predictSpawn)
			if (!GetGameObject()->BindToNetwork())
				return false;

	GetGameObject()->EnablePhysicsEvent(true, eEPE_OnCollisionLogged);

	LoadGeometry();
	Physicalize();

	IEntityRenderProxy *pProxy = static_cast<IEntityRenderProxy *>(GetEntity()->GetProxy(ENTITY_PROXY_RENDER));
	if (pProxy && pProxy->GetRenderNode())
	{
		pProxy->GetRenderNode()->SetViewDistRatio(255);
		pProxy->GetRenderNode()->SetLodRatio(255);
	}

	float lifetime = m_pAmmoParams->lifetime;
	if (lifetime > 0.0f)
		GetEntity()->SetTimer(ePTIMER_LIFETIME, (int)(lifetime*1000.0f));

	float showtime = m_pAmmoParams->showtime;
	if (showtime > 0.0f)
	{
		GetEntity()->SetSlotFlags(0, GetEntity()->GetSlotFlags(0)&(~ENTITY_SLOT_RENDER));
		GetEntity()->SetTimer(ePTIMER_SHOWTIME, (int)(showtime*1000.0f));
	}
	else
		GetEntity()->SetSlotFlags(0, GetEntity()->GetSlotFlags(0)|ENTITY_SLOT_RENDER);

	// Only for bullets
	m_hitPoints = m_pAmmoParams->hitPoints;
	m_hitListener = false;
	if(m_hitPoints>0)
	{
		//Only projectiles with hit points are hit listeners
		g_pGame->GetGameRules()->AddHitListener(this);
		m_hitListener = true;
		m_noBulletHits = m_pAmmoParams->noBulletHits;
	}

	if (m_tracked) // if this is true here, it means m_tracked was serialized from spawn info
	{
		m_tracked=false;
		SetTracked(true);
	}

	return true;
}
예제 #2
0
bool CVisibleObjectsHelper::CheckObjectViewDist(const Agent& agent, const SVisibleObject &visibleObject) const
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);

	assert(agent.IsValid());

	bool bInViewDist = true;

	IEntitySystem *pEntitySystem = gEnv->pEntitySystem;
	assert(pEntitySystem);

	IEntity *pAIEntity = pEntitySystem->GetEntity(agent.GetEntityID());
	IEntity *pObjectEntity = pEntitySystem->GetEntity(visibleObject.entityId);

	IEntityRenderProxy *pObjectRenderProxy = (pAIEntity != NULL && pObjectEntity ? static_cast<IEntityRenderProxy *>(pObjectEntity->GetProxy(ENTITY_PROXY_RENDER)) : NULL);
	if (pObjectRenderProxy != NULL)
	{
		IRenderNode *pObjectRenderNode = pObjectRenderProxy->GetRenderNode();
		if (pObjectRenderNode != NULL)
		{
			const float fDistanceSq = pAIEntity->GetWorldPos().GetSquaredDistance(pObjectEntity->GetWorldPos());
			const float fMaxViewDistSq = sqr(pObjectRenderNode->GetMaxViewDist());
			
			bInViewDist = (fDistanceSq <= fMaxViewDistSq);
		}
	}

	return bInViewDist;
}
IEntity* CLaserBeam::CreateLaserEntity()
{
	IEntity* pLaserEntity = gEnv->pEntitySystem->GetEntity(m_laserEntityId);
	if (pLaserEntity)
		return pLaserEntity;

	IEntity* pOwnerEntity = gEnv->pEntitySystem->GetEntity(m_ownerEntityId);
	if (!pOwnerEntity)
		return 0;

	SEntitySpawnParams spawnParams;
	spawnParams.pClass = gEnv->pEntitySystem->GetClassRegistry()->GetDefaultClass();
	spawnParams.sName = "LaserBeam";
	spawnParams.nFlags = (pOwnerEntity->GetFlags() | ENTITY_FLAG_NO_SAVE) & ~ENTITY_FLAG_CASTSHADOW;

	IEntity* pNewEntity = gEnv->pEntitySystem->SpawnEntity(spawnParams);

	if(pNewEntity)
	{
		m_laserEntityId = pNewEntity->GetId();


		IEntityRenderProxy *pRenderProxy = (IEntityRenderProxy*)pNewEntity->GetProxy(ENTITY_PROXY_RENDER);
		IRenderNode * pRenderNode = pRenderProxy?pRenderProxy->GetRenderNode():NULL;

		if(pRenderNode)
			pRenderNode->SetRndFlags(ERF_RENDER_ALWAYS,true);

		SetLaserEntitySlots(false);
	}

	return pNewEntity;
}
예제 #4
0
//------------------------------------------------------------------------
bool CProjectile::Init(IGameObject *pGameObject)
{
	SetGameObject(pGameObject);

	g_pGame->GetWeaponSystem()->AddProjectile(GetEntity(), this);

	if(!GetGameObject()->CaptureProfileManager(this))
		return false;

	m_pAmmoParams = g_pGame->GetWeaponSystem()->GetAmmoParams(GetEntity()->GetClass());

	if(0 == (GetEntity()->GetFlags() & (ENTITY_FLAG_CLIENT_ONLY | ENTITY_FLAG_SERVER_ONLY)))
		if(!m_pAmmoParams->predictSpawn)
			if(!GetGameObject()->BindToNetwork())
				return false;

	LoadGeometry();
	Physicalize();

	IEntityRenderProxy *pProxy = static_cast<IEntityRenderProxy *>(GetEntity()->GetProxy(ENTITY_PROXY_RENDER));

	if(pProxy && pProxy->GetRenderNode())
	{
		pProxy->GetRenderNode()->SetViewDistRatio(255);
		pProxy->GetRenderNode()->SetLodRatio(255);
	}

	float lifetime = m_pAmmoParams->lifetime;

	if(lifetime > 0.0f)
		GetEntity()->SetTimer(ePTIMER_LIFETIME, (int)(lifetime*1000.0f));

	float showtime = m_pAmmoParams->showtime;

	if(showtime > 0.0f)
	{
		GetEntity()->SetSlotFlags(0, GetEntity()->GetSlotFlags(0)&(~ENTITY_SLOT_RENDER));
		GetEntity()->SetTimer(ePTIMER_SHOWTIME, (int)(showtime*1000.0f));
	}
	else
		GetEntity()->SetSlotFlags(0, GetEntity()->GetSlotFlags(0)|ENTITY_SLOT_RENDER);

	return true;
}
예제 #5
0
파일: Flock.cpp 프로젝트: hybridsix/Code
void CFlock::UpdateBoidsViewDistRatio()
{
	IEntityRenderProxy *pRenderProxy = (IEntityRenderProxy*)m_pEntity->GetProxy(ENTITY_PROXY_RENDER);
	if (pRenderProxy)
	{
		m_nViewDistRatio = pRenderProxy->GetRenderNode()->GetViewDistRatio();
	}

	for (Boids::iterator it = m_boids.begin(); it != m_boids.end(); ++it)
	{
		CBoidObject* boid = *it;
		IEntity *pBoidEntity = gEnv->pEntitySystem->GetEntity(boid->m_entity);
		if (pBoidEntity)
		{
			pRenderProxy = (IEntityRenderProxy*)pBoidEntity->GetProxy(ENTITY_PROXY_RENDER);
			if (pRenderProxy)
			{
				pRenderProxy->GetRenderNode()->SetViewDistRatio(m_nViewDistRatio);
			}
		}
	}
}
예제 #6
0
void CUIEntityDynTexTag::OnAddTaggedEntity(EntityId entityId, const char *uiElementName, const char *entityClass, const char *materialTemplate, const Vec3 &offset, const char *idx)
{
    OnRemoveTaggedEntity(entityId, idx);

    IEntityClass *pEntClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(entityClass);

    if(pEntClass)
    {
        SEntitySpawnParams params;
        params.nFlags = ENTITY_FLAG_CLIENT_ONLY;
        params.pClass = pEntClass;

        IEntity *pTagEntity = gEnv->pEntitySystem->SpawnEntity(params);
        IUIElement *pElement = gEnv->pFlashUI->GetUIElement(uiElementName);

        if(pTagEntity && pElement)
        {
            IMaterial *pMatTemplate = gEnv->p3DEngine->GetMaterialManager()->LoadMaterial(materialTemplate, false);

            if(pMatTemplate && pMatTemplate->GetShaderItem().m_pShaderResources->GetTexture(0))
            {
                pMatTemplate->GetShaderItem().m_pShaderResources->GetTexture(0)->m_Name.Format("%s@%d.ui", uiElementName, entityId);
                IMaterial *pMat = gEnv->p3DEngine->GetMaterialManager()->CloneMaterial(pMatTemplate);
                pTagEntity->SetMaterial(pMat);
            }

            IEntityRenderProxy *pRenderProxy = (IEntityRenderProxy *) pTagEntity->GetProxy(ENTITY_PROXY_RENDER);

            if(pRenderProxy)
            {
                IRenderNode *pRenderNode = pRenderProxy->GetRenderNode();

                if(pRenderNode)
                {
                    pRenderNode->SetViewDistRatio(256);
                }
            }

            pElement->RemoveEventListener(this); // first remove to avoid assert if already registered!
            pElement->AddEventListener(this, "CUIEntityDynTexTag");
            gEnv->pEntitySystem->AddEntityEventListener(entityId, ENTITY_EVENT_DONE, this);
            m_Tags.push_back(STagInfo(entityId, pTagEntity->GetId(), idx, offset, pElement->GetInstance((uint)entityId)));
        }
    }
}
예제 #7
0
파일: ItemView.cpp 프로젝트: AiYong/CryGame
//------------------------------------------------------------------------
void CItem::CopyRenderFlags(IEntity *pOwner)
{
	if (!pOwner || !GetRenderProxy())
		return;

	IRenderNode *pRenderNode = GetRenderProxy()->GetRenderNode();
	if (pRenderNode)
	{
		IEntityRenderProxy *pOwnerRenderProxy = (IEntityRenderProxy *)pOwner->GetProxy(ENTITY_PROXY_RENDER);
		IRenderNode *pOwnerRenderNode = pOwnerRenderProxy?pOwnerRenderProxy->GetRenderNode():NULL;
		if (pOwnerRenderNode)
		{
			pRenderNode->SetViewDistRatio(pOwnerRenderNode->GetViewDistRatio());
			pRenderNode->SetLodRatio(pOwnerRenderNode->GetLodRatio());

			uint32 flags = pOwner->GetFlags()&(ENTITY_FLAG_CASTSHADOW);
			uint32 mflags = GetEntity()->GetFlags()&(~(ENTITY_FLAG_CASTSHADOW));
			GetEntity()->SetFlags(mflags|flags);
		}
	}
}
예제 #8
0
//---------------------------------------------------------------------------
void CLam::CreateLaserEntity()
{
    if(m_pLaserEntityId)
    {
        //Check if entity is valid
        IEntity *pEntity = m_pEntitySystem->GetEntity(m_pLaserEntityId);
        if(!pEntity)
            m_pLaserEntityId = 0;
    }

    if (!m_pLaserEntityId)
    {
        SEntitySpawnParams spawnParams;
        spawnParams.pClass = gEnv->pEntitySystem->GetClassRegistry()->GetDefaultClass();
        spawnParams.sName = "LAMLaser";
        spawnParams.nFlags = (GetEntity()->GetFlags() | ENTITY_FLAG_NO_SAVE) & ~ENTITY_FLAG_CASTSHADOW;

        IEntity *pNewEntity =gEnv->pEntitySystem->SpawnEntity(spawnParams);
        //assert(pNewEntity && "Laser entity could no be spawned!!");

        if(pNewEntity)
        {
            pNewEntity->FreeSlot(0);
            pNewEntity->FreeSlot(1);

            m_pLaserEntityId = pNewEntity->GetId();

            if(IEntity* pEntity = GetEntity())
                pEntity->AttachChild(pNewEntity);

            IEntityRenderProxy *pRenderProxy = (IEntityRenderProxy*)pNewEntity->GetProxy(ENTITY_PROXY_RENDER);
            IRenderNode * pRenderNode = pRenderProxy?pRenderProxy->GetRenderNode():NULL;

            if(pRenderNode)
                pRenderNode->SetRndFlags(ERF_RENDER_ALWAYS,true);

        }
    }
}
예제 #9
0
파일: Flock.cpp 프로젝트: hybridsix/Code
void CFlock::Update( CCamera *pCamera )
{
	FUNCTION_PROFILER( GetISystem(),PROFILE_ENTITY );

	if (!IsFlockActive())
		return;

	if (!m_e_flocks)
	{
		if (m_bEntityCreated)
			DeleteEntities( true );
		return;
	}

	if(GetISystem()->IsSerializingFile() == 1) //quickloading
		return;

	if (!m_bEntityCreated)
	{
		if (!CreateEntities())
			return;
	}

	float dt = gEnv->pTimer->GetFrameTime();
	// Make sure delta time is limited.
	if (dt > 1.0f)
		dt = 0.01f;
	if (dt > 0.1f)
		dt = 0.1f;

	m_bc.fSmoothFactor = 1.f - gEnv->pTimer->GetProfileFrameBlending();
	/*
	for (Boids::iterator it = m_boids.begin(); it != m_boids.end(); ++it)
	{
		CBoidObject *boid = *it;
		boid->Think();
	}
	*/
	//m_bc.playerPos = m_flockMgr->GetPlayerPos();

	m_bc.playerPos = GetISystem()->GetViewCamera().GetMatrix().GetTranslation(); // Player position is position of camera.
	m_bc.flockPos = m_origin;
	m_bc.waterLevel = m_bc.engine->GetWaterLevel( &m_origin );

	m_bounds.min = Vec3(FLT_MAX,FLT_MAX,FLT_MAX);
	m_bounds.max = Vec3(-FLT_MAX,-FLT_MAX,-FLT_MAX);

	int numBoids = m_boids.size();
	if (m_percentEnabled < 100)
	{
		numBoids = (m_percentEnabled*numBoids)/100;
	}

	if (!m_pEntity->GetRotation().IsIdentity())
	{
		// Entity matrix must not have rotation.
		//Quat q;
		//q.SetIdentity();
		//m_pEntity->SetRotation(q);
	}

	//////////////////////////////////////////////////////////////////////////
	// Update flock random center.
	//////////////////////////////////////////////////////////////////////////
	m_fCenterFloatingTime += gEnv->pTimer->GetFrameTime();
	float tc = m_fCenterFloatingTime*0.2f;
	m_bc.randomFlockCenter = m_bc.flockPos + 
		//m_bc.fSpawnRadius*Vec3(sinf(0.9f*m_fCenterFloatingTime),cosf(1.1f*sin(0.9f*m_fCenterFloatingTime)),0.3f*sinf(1.2f*m_fCenterFloatingTime) );
		m_bc.fSpawnRadius*Vec3(sinf(tc*0.913f)*cosf(tc*1.12f),sinf(tc*0.931f)*cosf(tc*0.971f),0.4f*sinf(tc*1.045f)*cosf(tc*0.962f) );
	//gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere( m_bc.randomFlockCenter,0.1f,ColorB(255,0,0,255) );

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

	//////////////////////////////////////////////////////////////////////////
	IEntityRenderProxy *pRenderProxy = (IEntityRenderProxy*)m_pEntity->GetProxy(ENTITY_PROXY_RENDER);
	if (pRenderProxy)
	{
		if (pRenderProxy->GetRenderNode()->GetViewDistRatio() != m_nViewDistRatio)
			UpdateBoidsViewDistRatio();
	}
	//////////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////////
	// Update scare factors.
	if (m_bc.scareThreatLevel > 0)
	{
		m_bc.scareThreatLevel *= 0.95f;
		m_bc.scareRatio *= 0.95f;
		if (m_bc.scareRatio < 0.01f)
		{
			m_bc.scareRatio = 0;
			m_bc.scareThreatLevel = 0;
		}
		if (m_e_flocks == 2)
		{
			int c = (int)(255*m_bc.scareRatio);
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere( m_bc.scarePoint,m_bc.scareRadius,ColorB(c,0,0,c),false );
		}
	}

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

	UpdateBoidCollisions();

	Vec3 entityPos = m_pEntity->GetWorldPos();
	Matrix34 boidTM;
	int num = 0;
	for (Boids::iterator it = m_boids.begin(); it != m_boids.end(); ++it,num++)
	{
		if (num > numBoids)
			break;

		CBoidObject* boid = *it;

		m_bc.terrainZ = m_bc.engine->GetTerrainElevation(boid->m_pos.x,boid->m_pos.y);
		boid->Update(dt,m_bc);

		if (!boid->m_physicsControlled && !boid->m_dead)
		{
			IEntity *pBoidEntity = gEnv->pEntitySystem->GetEntity(boid->m_entity);
			if (pBoidEntity)
			{
				Quat q(IDENTITY);
				boid->CalcOrientation(q);
				const Vec3 scaleVector(boid->m_scale,boid->m_scale,boid->m_scale);
				pBoidEntity->SetPosRotScale( boid->m_pos, q, scaleVector, ENTITY_XFORM_NO_SEND_TO_ENTITY_SYSTEM );
			}
		}

	}

	m_updateFrameID = gEnv->pRenderer->GetFrameID(false);	
	//gEnv->pLog->Log( "Birds Update" );
}
예제 #10
0
void CAreaProxy::ProcessEvent( SEntityEvent &event )
{
	switch(event.event) {
	case ENTITY_EVENT_XFORM:
		OnMove();
		break;
	case ENTITY_EVENT_SCRIPT_EVENT:
		{
			const char * pName = (const char*)event.nParam[0];
			if(!stricmp(pName, "Enable"))
				OnEnable(true);
			else if(!stricmp(pName, "Disable"))
				OnEnable(false);
		}
		break;
	case ENTITY_EVENT_RENDER:
		{
			if(m_pArea->GetAreaType()==ENTITY_AREA_TYPE_GRAVITYVOLUME)
			{
				if(!m_bDontDisableInvisible)
				{
					m_lastFrameTime = gEnv->pTimer->GetCurrTime();
				}
				if(!m_bIsEnableInternal)
				{
					m_bIsEnableInternal = true;
					OnEnable(m_bIsEnable, false);
					m_pEntity->SetTimer(0, 11000);
				}
			}
		}
		break;
	case ENTITY_EVENT_TIMER:
		{
			if(m_pArea->GetAreaType()==ENTITY_AREA_TYPE_GRAVITYVOLUME)
			{
				if(!m_bDontDisableInvisible)
				{
					bool bOff=false;
					if(gEnv->pTimer->GetCurrTime() - m_lastFrameTime > 10.0f)
					{
						bOff=true;
						IEntityRenderProxy * pEntPr = (IEntityRenderProxy *)m_pEntity->GetProxy(ENTITY_PROXY_RENDER);
						if(pEntPr)
						{
							IRenderNode * pRendNode = pEntPr->GetRenderNode();
							if(pRendNode)
							{
								if(pEntPr->IsRenderProxyVisAreaVisible())
									bOff = false;
							}
						}
						if(bOff)
						{
							m_bIsEnableInternal = false;
							OnEnable(m_bIsEnable, false);
						}
					}
					if(!bOff)
						m_pEntity->SetTimer(0, 11000);
				}
			}
		}
		break;
	}
}
예제 #11
0
    virtual void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo )
    {
        switch (event)
        {
        case eFE_Initialize:
            break;
        case eFE_Activate:
            IGameFramework* pGameFramework = gEnv->pGame->GetIGameFramework();

            if(IsPortActive(pActInfo, EIP_Cast))
            {
                // setup ray + optionally skip 1 entity
                ray_hit rayHit;
                static const float maxRayDist = 100.f;
                const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any;
                IPhysicalEntity	*skipList[1];
                int skipCount = 0;
                IEntity* skipEntity = gEnv->pEntitySystem->GetEntity(GetPortEntityId(pActInfo, EIP_SkipEntity));
                if(skipEntity)
                {
                    skipList[0] = skipEntity->GetPhysics();
                    skipCount = 1;
                }

                Vec3 rayPos = GetPortVec3(pActInfo, EIP_RayPos);
                Vec3 rayDir = GetPortVec3(pActInfo, EIP_RayDir);

                // Check if the ray hits an entity
                if(gEnv->pSystem->GetIPhysicalWorld()->RayWorldIntersection(rayPos, rayDir * 100, ent_all, flags, &rayHit, 1, skipList, skipCount))
                {
                    int type = rayHit.pCollider->GetiForeignData();

                    if (type == PHYS_FOREIGN_ID_ENTITY)
                    {
                        IEntity* pEntity = (IEntity*)rayHit.pCollider->GetForeignData(PHYS_FOREIGN_ID_ENTITY);
                        IEntityRenderProxy* pRenderProxy = pEntity ? (IEntityRenderProxy*)pEntity->GetProxy(ENTITY_PROXY_RENDER) : 0;

                        // Get the renderproxy, and use it to check if the material is a DynTex, and get the UIElement if so
                        if(pRenderProxy)
                        {
                            IRenderNode *pRenderNode = pRenderProxy->GetRenderNode();
                            IMaterial* pMaterial = pRenderProxy->GetRenderMaterial();
                            SEfResTexture* texture = 0;
                            if(pMaterial && pMaterial->GetShaderItem().m_pShaderResources)
                                texture= pMaterial->GetShaderItem().m_pShaderResources->GetTexture(EFTT_DIFFUSE);
                            IUIElement* pElement = texture ? gEnv->pFlashUI->GetUIElementByInstanceStr(texture->m_Name) : 0;

                            if(pElement && pRenderNode)
                            {
                                int m_dynTexGeomSlot = 0;
                                IStatObj* pObj = pRenderNode->GetEntityStatObj(m_dynTexGeomSlot);

                                // result
                                bool hasHit = false;
                                Vec2 uv0, uv1, uv2;
                                Vec3 p0, p1, p2;
                                Vec3 hitpos;


                                // calculate ray dir
                                CCamera cam = gEnv->pRenderer->GetCamera();
                                if (pEntity->GetSlotFlags(m_dynTexGeomSlot) & ENTITY_SLOT_RENDER_NEAREST)
                                {
                                    ICVar *r_drawnearfov = gEnv->pConsole->GetCVar("r_DrawNearFoV");
                                    assert(r_drawnearfov);
                                    cam.SetFrustum(cam.GetViewSurfaceX(),cam.GetViewSurfaceZ(),DEG2RAD(r_drawnearfov->GetFVal()),cam.GetNearPlane(),cam.GetFarPlane(), cam.GetPixelAspectRatio());
                                }

                                Vec3 vPos0 = rayPos;
                                Vec3 vPos1 = rayPos + rayDir;

                                // translate into object space
                                const Matrix34 m = pEntity->GetWorldTM().GetInverted();
                                vPos0 = m * vPos0;
                                vPos1 = m * vPos1;

                                // walk through all sub objects
                                const int objCount = pObj->GetSubObjectCount();
                                for (int obj = 0; obj <= objCount && !hasHit; ++obj)
                                {
                                    Vec3 vP0, vP1;
                                    IStatObj* pSubObj = NULL;

                                    if (obj == objCount)
                                    {
                                        vP0 = vPos0;
                                        vP1 = vPos1;
                                        pSubObj = pObj;
                                    }
                                    else
                                    {
                                        IStatObj::SSubObject* pSub = pObj->GetSubObject(obj);
                                        const Matrix34 mm = pSub->tm.GetInverted();
                                        vP0 = mm * vPos0;
                                        vP1 = mm * vPos1;
                                        pSubObj = pSub->pStatObj;
                                    }

                                    IRenderMesh* pMesh = pSubObj ? pSubObj->GetRenderMesh() : NULL;
                                    if (pMesh)
                                    {
                                        const Ray ray(vP0, (vP1-vP0).GetNormalized() * maxRayDist);
                                        hasHit = RayIntersectMesh(pMesh, pMaterial, pElement, ray, hitpos, p0, p1, p2, uv0, uv1, uv2);
                                    }
                                }

                                // skip if not hit
                                if (!hasHit)
                                {
                                    ActivateOutput(pActInfo, EOP_Failed, 1);
                                    return;
                                }

                                // calculate vectors from hitpos to vertices p0, p1 and p2:
                                const Vec3 v0 = p0-hitpos;
                                const Vec3 v1 = p1-hitpos;
                                const Vec3 v2 = p2-hitpos;

                                // calculate factors
                                const float h = (p0-p1).Cross(p0-p2).GetLength();
                                const float f0 = v1.Cross(v2).GetLength() / h;
                                const float f1 = v2.Cross(v0).GetLength() / h;
                                const float f2 = v0.Cross(v1).GetLength() / h;

                                // find the uv corresponding to hitpos
                                Vec3 uv = uv0 * f0 + uv1 * f1 + uv2 * f2;

                                // translate to flash space
                                int x, y, width, height;
                                float aspect;
                                pElement->GetFlashPlayer()->GetViewport(x, y, width, height, aspect);
                                int iX = int_round(uv.x * (float)width);
                                int iY = int_round(uv.y * (float)height);

                                // call the function provided if it is present in the UIElement description
                                string funcName = GetPortString(pActInfo, EIP_CallFunction);
                                const SUIEventDesc* eventDesc = pElement->GetFunctionDesc(funcName);
                                if(eventDesc)
                                {
                                    SUIArguments arg;
                                    arg.AddArgument(iX);
                                    arg.AddArgument(iY);
                                    pElement->CallFunction(eventDesc->sName, arg);
                                }

                                ActivateOutput(pActInfo, EOP_Success, 1);
                            }
                        }
                    }
                }

                ActivateOutput(pActInfo, EOP_Failed, 1);
            }

            break;
        }
    }