Пример #1
0
RenderList Wall::visibleBricks()
{
	RenderList renderList;
	for (int i = 0, e = m_bricks.size(); i < e; ++i) {
		if (m_bricks[i].visible()) {
			renderList.push_back(m_bricks[i].renderable());
		} else if (m_collisionManager) {
			m_collisionManager->removePassiveCollider(&m_bricks[i]);
		}
	}

	return renderList;
}
Пример #2
0
void LayerCache::update(Camera::Transform transform, RenderList& renderlist) {
    const double OVERDRAW = 2.5;
    renderlist.clear();
    m_needupdate = false;
    if(!m_layer->areInstancesVisible()) {
        FL_DBG(_log, "Layer instances hidden");
        return;
    }
    bool isWarped = transform == Camera::WarpedTransform;
    if( isWarped ) {
        fullUpdate();
    }

    Rect viewport = m_camera->getViewPort();
    Rect screen_viewport = viewport;
    double zoom = m_camera->getZoom();
    DoublePoint3D viewport_a = m_camera->screenToVirtualScreen(Point3D(viewport.x, viewport.y));
    DoublePoint3D viewport_b = m_camera->screenToVirtualScreen(Point3D(viewport.right(), viewport.bottom()));
    viewport.x = static_cast<int32_t>(std::min(viewport_a.x, viewport_b.x));
    viewport.y = static_cast<int32_t>(std::min(viewport_a.y, viewport_b.y));
    viewport.w = static_cast<int32_t>(std::max(viewport_a.x, viewport_b.x) - viewport.x);
    viewport.h = static_cast<int32_t>(std::max(viewport_a.y, viewport_b.y) - viewport.y);
    uint8_t layer_trans = m_layer->getLayerTransparency();

    double zmin = 0.0, zmax = 0.0;

    // FL_LOG(_log, LMsg("camera-update viewport") << viewport);
    std::vector<int32_t> index_list;
    collect(viewport, index_list);
    for(unsigned i=0; i!=index_list.size(); ++i) {
        Entry& entry = m_entries[index_list[i]];
        // NOTE
        // An update is forced if the item has an animation/action.
        // This update only happens if it is _already_ included in the viewport
        // Nevertheless: Moving instances - which might move into the viewport will be updated
        // By the layer change listener.
        if(entry.force_update || !isWarped) {
            updateEntry(entry);
        }

        RenderItem& item = m_instances[entry.instance_index];
        InstanceVisual* visual = item.instance->getVisual<InstanceVisual>();
        bool visible = (visual->isVisible() != 0);
        uint8_t instance_trans = visual->getTransparency();
        if(!item.image || !visible || (instance_trans == 255 && layer_trans == 0)
                || (instance_trans == 0 && layer_trans == 255)) {
            continue;
        }

        if(layer_trans != 0) {
            if(instance_trans != 0) {
                uint8_t calc_trans = layer_trans - instance_trans;
                if(calc_trans >= 0) {
                    instance_trans = calc_trans;
                } else {
                    instance_trans = 0;
                }
            } else {
                instance_trans = layer_trans;
            }
        }

        Point3D screen_point = m_camera->virtualScreenToScreen(item.screenpoint);
        // NOTE:
        // One would expect this to be necessary here,
        // however it works the same without, sofar
        // m_camera->calculateZValue(screen_point);
        // item.screenpoint.z = -screen_point.z;

        item.dimensions.x = screen_point.x;
        item.dimensions.y = screen_point.y;
        item.dimensions.w = item.bbox.w;
        item.dimensions.h = item.bbox.h;

        item.transparency = 255 - instance_trans;

        if (zoom != 1.0) {
            // NOTE: Due to image alignment, there is additional additions on image dimensions
            //       There's probabaly some better solution for this, but works "good enough" for now.
            //       In case additions are removed, gaps appear between tiles.
            item.dimensions.w = unsigned(double(item.bbox.w) * zoom + OVERDRAW);
            item.dimensions.h = unsigned(double(item.bbox.h) * zoom + OVERDRAW);
        }

        if (!m_need_sorting) {
            zmin = std::min(zmin, item.screenpoint.z);
            zmax = std::max(zmax, item.screenpoint.z);
        }

        if(item.dimensions.intersects(screen_viewport)) {
            renderlist.push_back(&item);
        }
    }

    if (m_need_sorting) {
        InstanceDistanceSort ids;
        std::stable_sort(renderlist.begin(), renderlist.end(), ids);
    } else {
        zmin -= 0.5;
        zmax += 0.5;

        // We want to put every z value in [-10,10] range.
        // To do it, we simply solve
        // { y1 = a*x1 + b
        // { y2 = a*x2 + b
        // where [y1,y2]' = [-10,10]' is required z range,
        // and [x1,x2]' is expected min,max z coords.
        double det = zmin - zmax;
        if (fabs(det) > FLT_EPSILON) {
            double det_a = -10.0 - 10.0;
            double det_b = 10.0 * zmin - (-10.0) * zmax;
            double a = static_cast<float>(det_a / det);
            double b = static_cast<float>(det_b / det);
            float estimate = sqrtf(static_cast<float>(renderlist.size()));
            float stack_delta = fabs(-10.0f - 10.0f) / estimate * 0.1f;

            RenderList::iterator it = renderlist.begin();
            for ( ; it != renderlist.end(); ++it) {
                double& z = (*it)->screenpoint.z;
                z = a * z + b;
                InstanceVisual* vis = (*it)->instance->getVisual<InstanceVisual>();
                z += vis->getStackPosition() * stack_delta;
            }
        }
    }
    //  FL_LOG(_log, LMsg("camera-update ") << " N=" <<renderlist.size() << "/" << m_instances.size() << "/" << index_list.size());
}