Exemplo n.º 1
0
bool DrawBatchList::appendLine( Viewport *vp, Vec2 p0, Vec2 p1, Color col, Vec2 trans, Vec2 scl, float radrot, int linew ) {
    DrawBatch *b = getCurrentBatch();
    bool to_continue = false;
    if( b && b->shouldContinue( vp, VFTYPE_COORD_COLOR, 0, GL_LINES, NULL, BLENDTYPE_SRC_ALPHA, linew ) && b->hasVertexRoom(2) ) {
        to_continue = true;
    }
    if(!to_continue) {
        b = startNextBatch( vp, VFTYPE_COORD_COLOR, 0, GL_LINES, NULL, BLENDTYPE_SRC_ALPHA, linew );
        if(!b) {
            print("appendline: can't start new batch");
            return false;
        }
    }
    Vec2 p0r( p0.x*scl.x, p0.y*scl.y );
    Vec2 p1r( p1.x*scl.x, p1.y*scl.y );
    float rotcos= ::cos(radrot), rotsin = ::sin(radrot);    
    Vec3 coords[2] = {
        Vec3(trans.x+ZROTX(p0r.x,p0r.y), trans.y+ZROTY(p0r.x,p0r.y), 0),
        Vec3(trans.x+ZROTX(p1r.x,p1r.y), trans.y+ZROTY(p1r.x,p1r.y), 0)
    };
    int inds[2] = { 0,1 };
    Color cols[2] = { col, col };
    b->pushVertices( 2, cols, coords, 2, inds );
    return true;
}
Exemplo n.º 2
0
void CompileThreadBlock::thread() {
    EditableMap::Lights& lights = wmap->get_light_sources();
    Tileset *ts = wmap->get_tileset_ptr();
    size_t nlgt = lights.size();
    int mw = wmap->get_width();
    int mh = wmap->get_height();
    int tw = ts->get_tile_width();
    int th = ts->get_tile_height();
    int w = mw * tw;
    int h = mh * th;
    short **pmap = wmap->get_map();
    short **pdeco = wmap->get_decoration();
    Point pr;

    for (size_t i = 0; i < nlgt; i++) {
        {
            Scope<Mutex> lock(mtx);
            finished_percent = 100 * (i + 1) / nlgt;
            if (cancelled) {
                break;
            }
        }
        int r = lights[i]->radius;
        int colr = lights[i]->r;
        int colg = lights[i]->g;
        int colb = lights[i]->b;
        int lmaxsq = r * r;
        int lx = lights[i]->x;
        int ly = lights[i]->y;
        Point p2(static_cast<float>(lx * tw + (tw / 2)), static_cast<float>(ly * th + (th / 2)));
        int lsx = static_cast<int>(p2.x) - r;
        int lsy = static_cast<int>(p2.y) - r;
        int lex = static_cast<int>(p2.x) + r;
        int ley = static_cast<int>(p2.y) + r;
        if (lsx < 0) lsx = 0;
        if (lsy < 0) lsy = 0;
        if (lex > w) lex = w;
        if (ley > h) ley = h;

        int txs = lsx / tw;
        int txe = lex / tw;
        int tys = lsy / th;
        int tye = ley / th;

        for (int y = lsy; y < ley; y++) {
            for (int x = lsx; x < lex; x++) {
                int dindex = pdeco[y / th][x / tw];
                if (dindex < 0) {
                    lightmap[y][x * 4 + 3] = 0;
                } else {
                    bool contact = false;
                    Point p1(static_cast<float>(x), static_cast<float>(y));
                    float xd = p2.x - p1.x;
                    float yd = p2.y - p1.y;
                    float dist = xd * xd + yd * yd;
                    if (dist < lmaxsq) {
                        for (int tx = txs; tx < txe; tx++) {
                            for (int ty = tys; ty < tye; ty++) {
                                short index = pmap[ty][tx];
                                if (index >= 0) {
                                    if (ts->get_tile(index)->is_light_blocking()) {
                                        Point p1l(static_cast<float>(tx * tw), static_cast<float>(ty * th));
                                        Point p2l(static_cast<float>(tx * tw), static_cast<float>((ty + 1) * th - 0.5f));
                                        Point p1r(static_cast<float>((tx + 1) * tw - 0.5f), static_cast<float>(ty * th));
                                        Point p2r(static_cast<float>((tx + 1) * tw - 0.5f), static_cast<float>((ty + 1) * th - 0.5f));
                                        Point p1t(static_cast<float>(tx * tw), static_cast<float>(ty * th));
                                        Point p2t(static_cast<float>((tx + 1) * tw - 0.5f), static_cast<float>(ty * th));
                                        Point p1b(static_cast<float>(tx * tw), static_cast<float>((ty + 1) * th - 0.5f));
                                        Point p2b(static_cast<float>((tx + 1) * tw - 0.5f), static_cast<float>((ty + 1) * th - 0.5f));
                                        if (intersection(p1, p2, p1l, p2l, pr) ||
                                            intersection(p1, p2, p1r, p2r, pr) ||
                                            intersection(p1, p2, p1t, p2t, pr) ||
                                            intersection(p1, p2, p1b, p2b, pr))
                                        {
                                            contact = true;
                                            break;
                                        }
                                    }
                                }
                            }
                            if (contact) {
                                break;
                            }
                        }
                    } else {
                        contact = true;
                    }
                    if (!contact) {
                        int v = static_cast<int>(sqrt(65025.0f * dist / lmaxsq));
                        if (v < lightmap[y][x * 4 + 3]) {
                            double l = 1.0 - (static_cast<double>(v) / 255.0);
                            lightmap[y][x * 4 + 0] = static_cast<unsigned char>(colr * l);
                            lightmap[y][x * 4 + 1] = static_cast<unsigned char>(colg * l);
                            lightmap[y][x * 4 + 2] = static_cast<unsigned char>(colb * l);
                            lightmap[y][x * 4 + 3] = v;
                        }
                    }
                }
            }
        }
    }

    Scope<Mutex> lock(mtx);
    finished = true;
}
// Generate a lathe by rotating the given polyline
void AProceduralLatheActor::GenerateLathe(const TArray<FVector>& InPoints, const int InSegments, TArray<FProceduralMeshTriangle>& OutTriangles)
{
	UE_LOG(LogClass, Log, TEXT("AProceduralLatheActor::Lathe POINTS %d"), InPoints.Num());

	TArray<FVector> verts;

	// precompute some trig
	float angle = FMath::DegreesToRadians(360.0f / InSegments);
	float sinA = FMath::Sin(angle);
	float cosA = FMath::Cos(angle);

	/*
	This implementation is rotation around the X Axis, other formulas below

	Z Axis Rotation
	x' = x*cos q - y*sin q
	y' = x*sin q + y*cos q
	z' = z

	X Axis Rotation
	y' = y*cos q - z*sin q
	z' = y*sin q + z*cos q
	x' = x

	Y Axis Rotation
	z' = z*cos q - x*sin q
	x' = z*sin q + x*cos q
	y' = y
	*/

	// Working point array, in which we keep the rotated line we draw with
	TArray<FVector> wp;
	for(int i = 0; i < InPoints.Num(); i++)
	{
		wp.Add(InPoints[i]);
	}

	// Add a first and last point on the axis to complete the OutTriangles
	FVector p0(wp[0].X, 0, 0);
	FVector pLast(wp[wp.Num() - 1].X, 0, 0);

	FProceduralMeshTriangle tri;
	// for each segment draw the OutTriangles clockwise for normals pointing out or counterclockwise for the opposite (this here does CW)
	for(int segment = 0; segment<InSegments; segment++)
	{

		for(int i = 0; i<InPoints.Num() - 1; i++)
		{
			FVector p1 = wp[i];
			FVector p2 = wp[i + 1];
			FVector p1r(p1.X, p1.Y*cosA - p1.Z*sinA, p1.Y*sinA + p1.Z*cosA);
			FVector p2r(p2.X, p2.Y*cosA - p2.Z*sinA, p2.Y*sinA + p2.Z*cosA);

			static const FColor Red(255, 51, 51);
			tri.Vertex0.Color = Red;
			tri.Vertex1.Color = Red;
			tri.Vertex2.Color = Red;

			if(i == 0)
			{
				tri.Vertex0.Position = p1;
				tri.Vertex1.Position = p0;
				tri.Vertex2.Position = p1r;
				OutTriangles.Add(tri);
			}

			tri.Vertex0.Position = p1;
			tri.Vertex1.Position = p1r;
			tri.Vertex2.Position = p2;
			OutTriangles.Add(tri);

			tri.Vertex0.Position = p2;
			tri.Vertex1.Position = p1r;
			tri.Vertex2.Position = p2r;
			OutTriangles.Add(tri);

			if(i == InPoints.Num() - 2)
			{
				tri.Vertex0.Position = p2;
				tri.Vertex1.Position = p2r;
				tri.Vertex2.Position = pLast;
				OutTriangles.Add(tri);
				wp[i + 1] = p2r;
			}

			wp[i] = p1r;
		}
	}
}
void CompileThreadPixel::thread() {
    EditableMap::Lights& lights = wmap->get_light_sources();
    Tileset *ts = wmap->get_tileset_ptr();
    size_t nlgt = lights.size();
    int mw = wmap->get_width();
    int mh = wmap->get_height();
    int tw = ts->get_tile_width();
    int th = ts->get_tile_height();
    int w = mw * tw;
    int h = mh * th;
    short **pmap = wmap->get_map();
    short **pdeco = wmap->get_decoration();
    Point pr;

    for (size_t i = 0; i < nlgt; i++) {
        {
            ScopeMutex lock(mtx);
            finished_percent = 100 * (i + 1) / nlgt;
        }
        int r = lights[i]->radius;
        int lmaxsq = r * r;
        int lx = lights[i]->x;
        int ly = lights[i]->y;
        Point p2(static_cast<float>(lx * tw + (tw / 2)), static_cast<float>(ly * th + (th / 2)));
        int lsx = static_cast<int>(p2.x) - r;
        int lsy = static_cast<int>(p2.y) - r;
        int lex = static_cast<int>(p2.x) + r;
        int ley = static_cast<int>(p2.y) + r;
        if (lsx < 0) lsx = 0;
        if (lsy < 0) lsy = 0;
        if (lex > w) lex = w;
        if (ley > h) ley = h;

        int txs = lsx / tw;
        int txe = lex / tw;
        int tys = lsy / th;
        int tye = ley / th;

        for (int y = lsy; y < ley; y++) {
            for (int x = lsx; x < lex; x++) {
                int dindex = pdeco[y / th][x / tw];
                if (dindex < 0) {
                    lightmap[y][x * 4 + 3] = 0;
                } else {
                    bool contact = false;
                    Point p1(static_cast<float>(x), static_cast<float>(y));
                    float xd = p2.x - p1.x;
                    float yd = p2.y - p1.y;
                    float dist = xd * xd + yd * yd;
                    if (dist < lmaxsq) {
                        for (int tx = txs; tx < txe; tx++) {
                            for (int ty = tys; ty < tye; ty++) {
                                short index = pmap[ty][tx];
                                if (index >= 0) {
                                    if (ts->get_tile(index)->is_light_blocking()) {
                                        TileGraphic *tg = ts->get_tile(index)->get_tilegraphic();
                                        TileGraphicGL *tggl = static_cast<TileGraphicGL *>(tg);
                                        if (tggl->get_bytes_per_pixel(0) < 4) {
                                            Point p1l(static_cast<float>(tx * tw), static_cast<float>(ty * th));
                                            Point p2l(static_cast<float>(tx * tw), static_cast<float>((ty + 1) * th - 0.5f));
                                            Point p1r(static_cast<float>((tx + 1) * tw - 0.5f), static_cast<float>(ty * th));
                                            Point p2r(static_cast<float>((tx + 1) * tw - 0.5f), static_cast<float>((ty + 1) * th - 0.5f));
                                            Point p1t(static_cast<float>(tx * tw), static_cast<float>(ty * th));
                                            Point p2t(static_cast<float>((tx + 1) * tw - 0.5f), static_cast<float>(ty * th));
                                            Point p1b(static_cast<float>(tx * tw), static_cast<float>((ty + 1) * th - 0.5f));
                                            Point p2b(static_cast<float>((tx + 1) * tw - 0.5f), static_cast<float>((ty + 1) * th - 0.5f));
                                            if (intersection(p1, p2, p1l, p2l, pr) ||
                                                intersection(p1, p2, p1r, p2r, pr) ||
                                                intersection(p1, p2, p1t, p2t, pr) ||
                                                intersection(p1, p2, p1b, p2b, pr))
                                            {
                                                contact = true;
                                                break;
                                            }
                                        } else {
                                            unsigned char *p = tggl->get_picture_array(0);
                                            for (int py = 0; py < th; py++) {
                                                for (int px = 0; px < tw; px++) {
                                                    if (p[3] == 255) {
                                                        Point p1v(static_cast<float>(tx * tw + px) + 0.5f, static_cast<float>(ty * th + py) - 0.5f);
                                                        Point p2v(static_cast<float>(tx * tw + px) + 0.5f, static_cast<float>(ty * th + py) + 0.5f);
                                                        Point p1h(static_cast<float>(tx * tw + px) - 0.5f, static_cast<float>(ty * th + py) + 0.5f);
                                                        Point p2h(static_cast<float>(tx * tw + px) + 0.5f, static_cast<float>(ty * th + py) + 0.5f);
                                                        if (intersection(p1, p2, p1v, p2v, pr) ||
                                                            intersection(p1, p2, p1h, p2h, pr))
                                                        {
                                                            contact = true;
                                                            break;
                                                        }
                                                    }
                                                    p += 4;
                                                }
                                                if (contact) {
                                                   break;
                                                }
                                            }
                                            if (contact) {
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                            if (contact) {
                                break;
                            }
                        }
                    } else {
                        contact = true;
                    }
                    if (!contact) {
                        int v = static_cast<int>(sqrt(65025.0f * dist / lmaxsq));
                        if (v < lightmap[y][x * 4 + 3]) {
                            lightmap[y][x * 4 + 3] = v;
                        }
                    }
                }
            }
        }
    }

    ScopeMutex lock(mtx);
    finished = true;
}
Exemplo n.º 5
0
void AQuadTree::Lathe(const TArray<FVector>& points, TArray<FGeneratedMeshTriangle>& triangles, int32 segments)
{
	UE_LOG(LogClass, Log, TEXT("AQuadTree::Lathe POINTS %d"), points.Num());

	// precompute some trig
	float angle = FMath::DegreesToRadians(360.0f / segments);
	float sinA = FMath::Sin(angle);
	float cosA = FMath::Cos(angle);
	
	
	//This implementation is rotation around the X Axis, other formulas below

	//Z Axis Rotation
	//x' = x*cos q - y*sin q
	//y' = x*sin q + y*cos q
	//z' = z

	//X Axis Rotation
	//y' = y*cos q - z*sin q
	//z' = y*sin q + z*cos q
	//x' = x

	//Y Axis Rotation
	//z' = z*cos q - x*sin q
	//x' = z*sin q + x*cos q
	//y' = y

	//Working point array, in which we keep the rotated line we draw with
	TArray<FVector> wp;
	for (int i = 0; i < points.Num(); i++) {
		wp.Add(points[i]);
	}

	// Add a first and last point on the axis to complete the triangles
	FVector p0(wp[0].X, 0, 0);
	FVector pLast(wp[wp.Num() - 1].X, 0, 0);

	FGeneratedMeshTriangle tri;
	//for each segment draw the triangles clockwise for normals pointing out or counterclockwise for the opposite (this here does CW)
	for (int segment = 0; segment<segments; segment++) {

		for (int i = 0; i<points.Num() - 1; i++) {
			FVector p1 = wp[i];
			FVector p2 = wp[i + 1];
			FVector p1r(p1.X, p1.Y*cosA - p1.Z*sinA, p1.Y*sinA + p1.Z*cosA);
			FVector p2r(p2.X, p2.Y*cosA - p2.Z*sinA, p2.Y*sinA + p2.Z*cosA);

			if (i == 0) {
				tri.Vertex0 = p1;
				tri.Vertex1 = p0;
				tri.Vertex2 = p1r;
				triangles.Add(tri);
			}

			tri.Vertex0 = p1;
			tri.Vertex1 = p1r;
			tri.Vertex2 = p2;
			triangles.Add(tri);

			tri.Vertex0 = p2;
			tri.Vertex1 = p1r;
			tri.Vertex2 = p2r;
			triangles.Add(tri);

			if (i == points.Num() - 2) {
				tri.Vertex0 = p2;
				tri.Vertex1 = p2r;
				tri.Vertex2 = pLast;
				triangles.Add(tri);
				wp[i + 1] = p2r;
			}

			wp[i] = p1r;
		}
	}
}