void CustomGeometry::SetGeometryDataAttr(const PODVector<unsigned char>& value)
{
    if (value.Empty())
        return;

    MemoryBuffer buffer(value);

    SetNumGeometries(buffer.ReadVLE());
    elementMask_ = buffer.ReadUInt();

    for (unsigned i = 0; i < geometries_.Size(); ++i)
    {
        unsigned numVertices = buffer.ReadVLE();
        vertices_[i].Resize(numVertices);
        primitiveTypes_[i] = (PrimitiveType)buffer.ReadUByte();

        for (unsigned j = 0; j < numVertices; ++j)
        {
            if (elementMask_ & MASK_POSITION)
                vertices_[i][j].position_ = buffer.ReadVector3();
            if (elementMask_ & MASK_NORMAL)
                vertices_[i][j].normal_ = buffer.ReadVector3();
            if (elementMask_ & MASK_COLOR)
                vertices_[i][j].color_ = buffer.ReadUInt();
            if (elementMask_ & MASK_TEXCOORD1)
                vertices_[i][j].texCoord_ = buffer.ReadVector2();
            if (elementMask_ & MASK_TANGENT)
                vertices_[i][j].tangent_ = buffer.ReadVector4();
        }
    }

    Commit();
}
Beispiel #2
0
void CrowdAgent::SetAgentDataAttr(const PODVector<unsigned char>& value)
{
    if (value.Empty())
        return;

    dtCrowdAgent* agent = const_cast<dtCrowdAgent*>(GetDetourCrowdAgent());
    if (!agent)
        return;

    MemoryBuffer buffer(value);

    // Path corridor is tricky
    char corridorData[sizeof(dtPathCorridor)];
    // Duplicate the existing path corridor into a block
    memcpy(corridorData, &agent->corridor, sizeof(dtPathCorridor));

    // Read the entire block of the crowd agent
    buffer.Read(agent, sizeof(dtCrowdAgent));
    // Restore the values of the original path corridor
    memcpy(&agent->corridor, corridorData, sizeof(dtPathCorridor));
    // Tell the path corridor to rebuild the path, it will reevaluate the path, existing velocities maintained
    agent->corridor.reset(agent->targetRef, agent->targetPos);

    agent->params.userData = this;
}
Beispiel #3
0
static void ClipPolygon(PODVector<DecalVertex>& dest, const PODVector<DecalVertex>& src, const Plane& plane, bool skinned)
{
    unsigned last = 0;
    float lastDistance = 0.0f;
    dest.Clear();

    if (src.Empty())
        return;

    for (unsigned i = 0; i < src.Size(); ++i)
    {
        float distance = plane.Distance(src[i].position_);
        if (distance >= 0.0f)
        {
            if (lastDistance < 0.0f)
                dest.Push(ClipEdge(src[last], src[i], lastDistance, distance, skinned));

            dest.Push(src[i]);
        }
        else
        {
            if (lastDistance >= 0.0f && i != 0)
                dest.Push(ClipEdge(src[last], src[i], lastDistance, distance, skinned));
        }

        last = i;
        lastDistance = distance;
    }

    // Recheck the distances of the last and first vertices and add the final clipped vertex if applicable
    float distance = plane.Distance(src[0].position_);
    if ((lastDistance < 0.0f && distance >= 0.0f) || (lastDistance >= 0.0f && distance < 0.0f))
        dest.Push(ClipEdge(src[last], src[0], lastDistance, distance, skinned));
}
void UIBatch::AddOrMerge(const UIBatch& batch, PODVector<UIBatch>& batches)
{
    if (batch.vertexEnd_ == batch.vertexStart_)
        return;
    
    if (!batches.Empty() && batches.Back().Merge(batch))
        return;
    
    batches.Push(batch);
}
Beispiel #5
0
void CollisionChain2D::SetVerticesAttr(const PODVector<unsigned char>& value)
{
    if (value.Empty())
        return;

    PODVector<Vector2> vertices;

    MemoryBuffer buffer(value);
    while (!buffer.IsEof())
        vertices.Push(buffer.ReadVector2());

    SetVertices(vertices);
}
Beispiel #6
0
void UI::SetVertexData(VertexBuffer* dest, const PODVector<float>& vertexData)
{
    if (vertexData.Empty())
        return;

    // Update quad geometry into the vertex buffer
    // Resize the vertex buffer first if too small or much too large
    unsigned numVertices = vertexData.Size() / UI_VERTEX_SIZE;
    if (dest->GetVertexCount() < numVertices || dest->GetVertexCount() > numVertices * 2)
        dest->SetSize(numVertices, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1, true);

    dest->SetData(&vertexData[0]);
}
Beispiel #7
0
void DynamicNavigationMesh::SetNavigationDataAttr(const PODVector<unsigned char>& value)
{
    ReleaseNavigationMesh();

    if (value.Empty())
        return;

    MemoryBuffer buffer(value);
    boundingBox_ = buffer.ReadBoundingBox();
    numTilesX_ = buffer.ReadInt();
    numTilesZ_ = buffer.ReadInt();

    dtNavMeshParams params;     // NOLINT(hicpp-member-init)
    buffer.Read(&params, sizeof(dtNavMeshParams));

    navMesh_ = dtAllocNavMesh();
    if (!navMesh_)
    {
        URHO3D_LOGERROR("Could not allocate navigation mesh");
        return;
    }

    if (dtStatusFailed(navMesh_->init(&params)))
    {
        URHO3D_LOGERROR("Could not initialize navigation mesh");
        ReleaseNavigationMesh();
        return;
    }

    dtTileCacheParams tcParams;     // NOLINT(hicpp-member-init)
    buffer.Read(&tcParams, sizeof(tcParams));

    tileCache_ = dtAllocTileCache();
    if (!tileCache_)
    {
        URHO3D_LOGERROR("Could not allocate tile cache");
        ReleaseNavigationMesh();
        return;
    }
    if (dtStatusFailed(tileCache_->init(&tcParams, allocator_.Get(), compressor_.Get(), meshProcessor_.Get())))
    {
        URHO3D_LOGERROR("Could not initialize tile cache");
        ReleaseNavigationMesh();
        return;
    }

    ReadTiles(buffer, true);
    // \todo Shall we send E_NAVIGATION_MESH_REBUILT here?
}
VertexDeclaration::VertexDeclaration(Graphics* graphics, ShaderVariation* vertexShader, VertexBuffer** vertexBuffers,
                                     unsigned* elementMasks) :
    inputLayout_(0)
{
    PODVector<D3D11_INPUT_ELEMENT_DESC> elementDescs;

    unsigned vbElementMask = 0;

    for (unsigned i = 0; i < MAX_VERTEX_STREAMS; ++i)
    {
        if (vertexBuffers[i] && elementMasks[i])
        {
            for (unsigned j = 0; j < MAX_VERTEX_ELEMENTS; ++j)
            {
                if (elementMasks[i] & (1 << j))
                {
                    D3D11_INPUT_ELEMENT_DESC newDesc;
                    newDesc.SemanticName = VertexBuffer::elementSemantics[j];
                    newDesc.SemanticIndex = VertexBuffer::elementSemanticIndices[j];
                    newDesc.Format = (DXGI_FORMAT)VertexBuffer::elementFormats[j];
                    newDesc.InputSlot = (UINT)i;
                    newDesc.AlignedByteOffset = vertexBuffers[i]->GetElementOffset((VertexElement)j);
                    newDesc.InputSlotClass = (j >= ELEMENT_INSTANCEMATRIX1 && j <= ELEMENT_INSTANCEMATRIX3) ?
                                             D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
                    newDesc.InstanceDataStepRate = (j >= ELEMENT_INSTANCEMATRIX1 && j <= ELEMENT_INSTANCEMATRIX3) ? 1 : 0;
                    elementDescs.Push(newDesc);
                    vbElementMask |= 1 << j;
                }
            }
        }
    }

    if (elementDescs.Empty())
        return;

    ID3D11InputLayout* d3dInputLayout = 0;
    const PODVector<unsigned char>& byteCode = vertexShader->GetByteCode();

    graphics->GetImpl()->GetDevice()->CreateInputLayout(&elementDescs[0], (UINT)elementDescs.Size(), &byteCode[0],
            byteCode.Size(), &d3dInputLayout);
    if (d3dInputLayout)
        inputLayout_ = d3dInputLayout;
    else
        URHO3D_LOGERRORF("Failed to create input layout for shader %s, missing element mask %d",
                         vertexShader->GetFullName().CString(), vertexShader->GetElementMask() & ~vbElementMask);
}
Beispiel #9
0
RigidBody2D* PhysicsWorld2D::GetRigidBody(int screenX, int screenY, unsigned collisionMask, Camera* camera)
{
    if (!camera)
    {
        PODVector<Camera*> cameras;
        GetScene()->GetComponents<Camera>(cameras, true);
        if (!cameras.Empty())
            camera = cameras[0];
    }

    if (!camera)
    {
        LOGWARNING("Could not find camera in scene");
        return 0;
    }

    Graphics* graphics = GetSubsystem<Graphics>();
    Vector3 screenPoint((float)screenX / graphics->GetWidth(), (float)screenY / graphics->GetHeight(), 0.0f);
    Vector3 worldPoint = camera->ScreenToWorldPoint(screenPoint);

    return GetRigidBody(Vector2(worldPoint.x_, worldPoint.y_), collisionMask);
}
Beispiel #10
0
void DecalSet::SetDecalsAttr(const PODVector<unsigned char>& value)
{
    RemoveAllDecals();

    if (value.Empty())
        return;

    MemoryBuffer buffer(value);

    skinned_ = buffer.ReadBool();
    unsigned numDecals = buffer.ReadVLE();

    while (numDecals--)
    {
        decals_.Resize(decals_.Size() + 1);
        Decal& newDecal = decals_.Back();

        newDecal.timer_ = buffer.ReadFloat();
        newDecal.timeToLive_ = buffer.ReadFloat();
        newDecal.vertices_.Resize(buffer.ReadVLE());
        newDecal.indices_.Resize(buffer.ReadVLE());

        for (PODVector<DecalVertex>::Iterator i = newDecal.vertices_.Begin(); i != newDecal.vertices_.End(); ++i)
        {
            i->position_ = buffer.ReadVector3();
            i->normal_ = buffer.ReadVector3();
            i->texCoord_ = buffer.ReadVector2();
            i->tangent_ = buffer.ReadVector4();
            if (skinned_)
            {
                for (unsigned j = 0; j < 4; ++j)
                    i->blendWeights_[j] = buffer.ReadFloat();
                for (unsigned j = 0; j < 4; ++j)
                    i->blendIndices_[j] = buffer.ReadUByte();
            }
        }

        for (PODVector<unsigned short>::Iterator i = newDecal.indices_.Begin(); i != newDecal.indices_.End(); ++i)
            *i = buffer.ReadUShort();

        newDecal.CalculateBoundingBox();
        numVertices_ += newDecal.vertices_.Size();
        numIndices_ += newDecal.indices_.Size();
    }

    if (skinned_)
    {
        unsigned numBones = buffer.ReadVLE();
        skinMatrices_.Resize(numBones);
        bones_.Resize(numBones);

        for (unsigned i = 0; i < numBones; ++i)
        {
            Bone& newBone = bones_[i];

            newBone.name_ = buffer.ReadString();
            newBone.collisionMask_ = buffer.ReadUByte();
            if (newBone.collisionMask_ & BONECOLLISION_SPHERE)
                newBone.radius_ = buffer.ReadFloat();
            if (newBone.collisionMask_ & BONECOLLISION_BOX)
                newBone.boundingBox_ = buffer.ReadBoundingBox();
            buffer.Read(&newBone.offsetMatrix_.m00_, sizeof(Matrix3x4));
        }

        assignBonesPending_ = true;
        skinningDirty_ = true;
    }

    UpdateEventSubscription(true);
    UpdateBatch();
    MarkDecalsDirty();
}
VertexDeclaration::VertexDeclaration(Graphics* graphics, ShaderVariation* vertexShader, VertexBuffer** vertexBuffers) :
    inputLayout_(0)
{
    PODVector<D3D11_INPUT_ELEMENT_DESC> elementDescs;
    unsigned prevBufferDescs = 0;

    for (unsigned i = 0; i < MAX_VERTEX_STREAMS; ++i)
    {
        if (!vertexBuffers[i])
            continue;

        const PODVector<VertexElement>& srcElements = vertexBuffers[i]->GetElements();
        bool isExisting = false;

        for (unsigned j = 0; j < srcElements.Size(); ++j)
        {
            const VertexElement& srcElement = srcElements[j];
            const char* semanticName = ShaderVariation::elementSemanticNames[srcElement.semantic_];

            // Override existing element if necessary
            for (unsigned k = 0; k < prevBufferDescs; ++k)
            {
                if (elementDescs[k].SemanticName == semanticName && elementDescs[k].SemanticIndex == srcElement.index_)
                {
                    isExisting = true;
                    elementDescs[k].InputSlot = i;
                    elementDescs[k].AlignedByteOffset = srcElement.offset_;
                    elementDescs[k].InputSlotClass = srcElement.perInstance_ ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
                    elementDescs[k].InstanceDataStepRate = srcElement.perInstance_ ? 1 : 0;
                    break;
                }
            }

            if (isExisting)
                continue;

            D3D11_INPUT_ELEMENT_DESC newDesc;
            newDesc.SemanticName = semanticName;
            newDesc.SemanticIndex = srcElement.index_;
            newDesc.Format = d3dElementFormats[srcElement.type_];
            newDesc.InputSlot = (UINT)i;
            newDesc.AlignedByteOffset = srcElement.offset_;
            newDesc.InputSlotClass = srcElement.perInstance_ ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
            newDesc.InstanceDataStepRate = srcElement.perInstance_ ? 1 : 0;
            elementDescs.Push(newDesc);
        }

        prevBufferDescs = elementDescs.Size();
    }

    if (elementDescs.Empty())
        return;

    const PODVector<unsigned char>& byteCode = vertexShader->GetByteCode();

    HRESULT hr = graphics->GetImpl()->GetDevice()->CreateInputLayout(&elementDescs[0], (UINT)elementDescs.Size(), &byteCode[0],
        byteCode.Size(), (ID3D11InputLayout**)&inputLayout_);
    if (FAILED(hr))
    {
        ATOMIC_SAFE_RELEASE(inputLayout_);
        ATOMIC_LOGERRORF("Failed to create input layout for shader %s due to missing vertex element(s) (HRESULT %x)",
            vertexShader->GetFullName().CString(), (unsigned)hr);
    }
}
void DynamicNavigationMesh::SetNavigationDataAttr(const PODVector<unsigned char>& value)
{
    ReleaseNavigationMesh();

    if (value.Empty())
        return;

    MemoryBuffer buffer(value);
    boundingBox_ = buffer.ReadBoundingBox();
    numTilesX_ = buffer.ReadInt();
    numTilesZ_ = buffer.ReadInt();

    dtNavMeshParams params;
    buffer.Read(&params, sizeof(dtNavMeshParams));

    navMesh_ = dtAllocNavMesh();
    if (!navMesh_)
    {
        LOGERROR("Could not allocate navigation mesh");
        return;
    }

    if (dtStatusFailed(navMesh_->init(&params)))
    {
        LOGERROR("Could not initialize navigation mesh");
        ReleaseNavigationMesh();
        return;
    }

    dtTileCacheParams tcParams;
    buffer.Read(&tcParams, sizeof(tcParams));

    tileCache_ = dtAllocTileCache();
    if (!tileCache_)
    {
        LOGERROR("Could not allocate tile cache");
        ReleaseNavigationMesh();
        return;
    }
    if (dtStatusFailed(tileCache_->init(&tcParams, allocator_, compressor_, meshProcessor_)))
    {
        LOGERROR("Could not initialize tile cache");
        ReleaseNavigationMesh();
        return;
    }

    while (!buffer.IsEof())
    {
        dtTileCacheLayerHeader header;
        buffer.Read(&header, sizeof(dtTileCacheLayerHeader));
        const int dataSize = buffer.ReadInt();
        unsigned char* data = (unsigned char*)dtAlloc(dataSize, DT_ALLOC_PERM);
        buffer.Read(data, dataSize);

        if (dtStatusFailed(tileCache_->addTile(data, dataSize, DT_TILE_FREE_DATA, 0)))
        {
            LOGERROR("Failed to add tile");
            dtFree(data);
            return;
        }
    }

    for (int x = 0; x < numTilesX_; ++x)
    {
        for (int z = 0; z < numTilesZ_; ++z)
            tileCache_->buildNavMeshTilesAt(x, z, navMesh_);
    }

    tileCache_->update(0, navMesh_);
}
void NavigationMesh::SetNavigationDataAttr(const PODVector<unsigned char>& value)
{
    ReleaseNavigationMesh();

    if (value.Empty())
        return;

    MemoryBuffer buffer(value);

    boundingBox_ = buffer.ReadBoundingBox();
    numTilesX_ = buffer.ReadInt();
    numTilesZ_ = buffer.ReadInt();

    dtNavMeshParams params;
    rcVcopy(params.orig, &boundingBox_.min_.x_);
    params.tileWidth = buffer.ReadFloat();
    params.tileHeight = buffer.ReadFloat();
    params.maxTiles = buffer.ReadInt();
    params.maxPolys = buffer.ReadInt();

    navMesh_ = dtAllocNavMesh();
    if (!navMesh_)
    {
        ATOMIC_LOGERROR("Could not allocate navigation mesh");
        return;
    }

    if (dtStatusFailed(navMesh_->init(&params)))
    {
        ATOMIC_LOGERROR("Could not initialize navigation mesh");
        ReleaseNavigationMesh();
        return;
    }

    unsigned numTiles = 0;

    while (!buffer.IsEof())
    {
        /*int x =*/ buffer.ReadInt();
        /*int z =*/ buffer.ReadInt();
        /*dtTileRef tileRef =*/ buffer.ReadUInt();
        unsigned navDataSize = buffer.ReadUInt();

        unsigned char* navData = (unsigned char*)dtAlloc(navDataSize, DT_ALLOC_PERM);
        if (!navData)
        {
            ATOMIC_LOGERROR("Could not allocate data for navigation mesh tile");
            return;
        }

        buffer.Read(navData, navDataSize);
        if (dtStatusFailed(navMesh_->addTile(navData, navDataSize, DT_TILE_FREE_DATA, 0, 0)))
        {
            ATOMIC_LOGERROR("Failed to add navigation mesh tile");
            dtFree(navData);
            return;
        }
        else
            ++numTiles;
    }

    ATOMIC_LOGDEBUG("Created navigation mesh with " + String(numTiles) + " tiles from serialized data");
}
Beispiel #14
0
void UI::Render(VertexBuffer* buffer, const PODVector<UIBatch>& batches, unsigned batchStart, unsigned batchEnd)
{

    if (batches.Empty())
        return;

    Vector2 invScreenSize(1.0f / (float)graphics_->GetWidth(), 1.0f / (float)graphics_->GetHeight());
    Vector2 scale(2.0f * invScreenSize.x_, -2.0f * invScreenSize.y_);
    Vector2 offset(-1.0f, 1.0f);

    Matrix4 projection(Matrix4::IDENTITY);
    projection.m00_ = scale.x_;
    projection.m03_ = offset.x_;
    projection.m11_ = scale.y_;
    projection.m13_ = offset.y_;
    projection.m22_ = 1.0f;
    projection.m23_ = 0.0f;
    projection.m33_ = 1.0f;

    graphics_->ClearParameterSources();
    graphics_->SetColorWrite(true);
    graphics_->SetCullMode(CULL_NONE);
    graphics_->SetDepthTest(CMP_ALWAYS);
    graphics_->SetDepthWrite(false);
    graphics_->SetFillMode(FILL_SOLID);
    graphics_->SetStencilTest(false);

    graphics_->ResetRenderTargets();

    graphics_->SetVertexBuffer(buffer);

    ShaderVariation* noTextureVS = graphics_->GetShader(VS, "Basic", "VERTEXCOLOR");
    ShaderVariation* diffTextureVS = graphics_->GetShader(VS, "Basic", "DIFFMAP VERTEXCOLOR");
    ShaderVariation* noTexturePS = graphics_->GetShader(PS, "Basic", "VERTEXCOLOR");
    ShaderVariation* diffTexturePS = graphics_->GetShader(PS, "Basic", "DIFFMAP VERTEXCOLOR");
    ShaderVariation* diffMaskTexturePS = graphics_->GetShader(PS, "Basic", "DIFFMAP ALPHAMASK VERTEXCOLOR");
    ShaderVariation* alphaTexturePS = graphics_->GetShader(PS, "Basic", "ALPHAMAP VERTEXCOLOR");

    unsigned alphaFormat = Graphics::GetAlphaFormat();

    for (unsigned i = batchStart; i < batchEnd; ++i)
    {
        const UIBatch& batch = batches[i];
        if (batch.vertexStart_ == batch.vertexEnd_)
            continue;

        ShaderVariation* ps;
        ShaderVariation* vs;

        if (!batch.texture_)
        {
            ps = noTexturePS;
            vs = noTextureVS;
        }
        else
        {
            // If texture contains only an alpha channel, use alpha shader (for fonts)
            vs = diffTextureVS;

            if (batch.texture_->GetFormat() == alphaFormat)
                ps = alphaTexturePS;
            else if (batch.blendMode_ != BLEND_ALPHA && batch.blendMode_ != BLEND_ADDALPHA && batch.blendMode_ != BLEND_PREMULALPHA)
                ps = diffMaskTexturePS;
            else
                ps = diffTexturePS;
        }

        graphics_->SetShaders(vs, ps);
        if (graphics_->NeedParameterUpdate(SP_OBJECT, this))
            graphics_->SetShaderParameter(VSP_MODEL, Matrix3x4::IDENTITY);
        if (graphics_->NeedParameterUpdate(SP_CAMERA, this))
            graphics_->SetShaderParameter(VSP_VIEWPROJ, projection);
        if (graphics_->NeedParameterUpdate(SP_MATERIAL, this))
            graphics_->SetShaderParameter(PSP_MATDIFFCOLOR, Color(1.0f, 1.0f, 1.0f, 1.0f));

        graphics_->SetBlendMode(batch.blendMode_);
        graphics_->SetScissorTest(true, batch.scissor_);
        graphics_->SetTexture(0, batch.texture_);
        graphics_->Draw(TRIANGLE_LIST, batch.vertexStart_ / UI_VERTEX_SIZE, (batch.vertexEnd_ - batch.vertexStart_) /
            UI_VERTEX_SIZE);
    }
}
Beispiel #15
0
    /// Convert screen coordinates to element coordinates.
    IntVector2 ScreenToElement(const IntVector2& screenPos) override
    {
        IntVector2 result(-1, -1);

        if (node_.Expired())
            return result;

        Scene* scene = node_->GetScene();
        auto* model = node_->GetComponent<StaticModel>();
        if (scene == nullptr || model == nullptr)
            return result;

        auto* renderer = GetSubsystem<Renderer>();
        if (renderer == nullptr)
            return result;

        // \todo Always uses the first viewport, in case there are multiple
        auto* octree = scene->GetComponent<Octree>();
        if (viewport_ == nullptr)
            viewport_ = renderer->GetViewportForScene(scene, 0);

        if (viewport_.Expired() || octree == nullptr)
            return result;

        if (viewport_->GetScene() != scene)
        {
            URHO3D_LOGERROR("UIComponent and Viewport set to component's root element belong to different scenes.");
            return result;
        }

        Camera* camera = viewport_->GetCamera();

        if (camera == nullptr)
            return result;

        IntRect rect = viewport_->GetRect();
        if (rect == IntRect::ZERO)
        {
            auto* graphics = GetSubsystem<Graphics>();
            rect.right_ = graphics->GetWidth();
            rect.bottom_ = graphics->GetHeight();
        }

        Ray ray(camera->GetScreenRay((float)screenPos.x_ / rect.Width(), (float)screenPos.y_ / rect.Height()));
        PODVector<RayQueryResult> queryResultVector;
        RayOctreeQuery query(queryResultVector, ray, RAY_TRIANGLE_UV, M_INFINITY, DRAWABLE_GEOMETRY, DEFAULT_VIEWMASK);

        octree->Raycast(query);

        if (queryResultVector.Empty())
            return result;

        for (unsigned i = 0; i < queryResultVector.Size(); i++)
        {
            RayQueryResult& queryResult = queryResultVector[i];
            if (queryResult.drawable_ != model)
            {
                // ignore billboard sets by default
                if (queryResult.drawable_->GetTypeInfo()->IsTypeOf(BillboardSet::GetTypeStatic()))
                    continue;
                return result;
            }

            Vector2& uv = queryResult.textureUV_;
            result = IntVector2(static_cast<int>(uv.x_ * GetWidth()),
                static_cast<int>(uv.y_ * GetHeight()));
            return result;
        }
        return result;
    }