| 3911 | } |
| 3912 | |
| 3913 | void PixelGameEngine::DrawPartialWarpedDecal(olc::Decal* decal, const olc::vf2d* pos, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint) |
| 3914 | { |
| 3915 | DecalInstance di; |
| 3916 | di.points = 4; |
| 3917 | di.decal = decal; |
| 3918 | di.tint = { tint, tint, tint, tint }; |
| 3919 | di.w = { 1, 1, 1, 1 }; |
| 3920 | di.pos.resize(4); |
| 3921 | di.uv = { { 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f} }; |
| 3922 | olc::vf2d center; |
| 3923 | float rd = ((pos[2].x - pos[0].x) * (pos[3].y - pos[1].y) - (pos[3].x - pos[1].x) * (pos[2].y - pos[0].y)); |
| 3924 | if (rd != 0) |
| 3925 | { |
| 3926 | olc::vf2d uvtl = source_pos * decal->vUVScale; |
| 3927 | olc::vf2d uvbr = uvtl + (source_size * decal->vUVScale); |
| 3928 | di.uv = { { uvtl.x, uvtl.y }, { uvtl.x, uvbr.y }, { uvbr.x, uvbr.y }, { uvbr.x, uvtl.y } }; |
| 3929 | |
| 3930 | rd = 1.0f / rd; |
| 3931 | float rn = ((pos[3].x - pos[1].x) * (pos[0].y - pos[1].y) - (pos[3].y - pos[1].y) * (pos[0].x - pos[1].x)) * rd; |
| 3932 | float sn = ((pos[2].x - pos[0].x) * (pos[0].y - pos[1].y) - (pos[2].y - pos[0].y) * (pos[0].x - pos[1].x)) * rd; |
| 3933 | if (!(rn < 0.f || rn > 1.f || sn < 0.f || sn > 1.f)) center = pos[0] + rn * (pos[2] - pos[0]); |
| 3934 | float d[4]; for (int i = 0; i < 4; i++) d[i] = (pos[i] - center).mag(); |
| 3935 | for (int i = 0; i < 4; i++) |
| 3936 | { |
| 3937 | float q = d[i] == 0.0f ? 1.0f : (d[i] + d[(i + 2) & 3]) / d[(i + 2) & 3]; |
| 3938 | di.uv[i] *= q; di.w[i] *= q; |
| 3939 | di.pos[i] = { (pos[i].x * vInvScreenSize.x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f }; |
| 3940 | } |
| 3941 | di.mode = nDecalMode; |
| 3942 | di.structure = nDecalStructure; |
| 3943 | vLayers[nTargetLayer].vecDecalInstance.push_back(di); |
| 3944 | } |
| 3945 | } |
| 3946 | |
| 3947 | void PixelGameEngine::DrawWarpedDecal(olc::Decal* decal, const olc::vf2d* pos, const olc::Pixel& tint) |
| 3948 | { |