| 1011 | } |
| 1012 | |
| 1013 | void Object::DrawDecal(int forceLOD, ClipFlags clipFlags, const FrameBase& pos) |
| 1014 | { |
| 1015 | if (forceLOD == LOD_INVISIBLE) |
| 1016 | { |
| 1017 | return; // invisible LOD |
| 1018 | } |
| 1019 | |
| 1020 | #if ALPHA_SPLIT |
| 1021 | bool alpha = true; |
| 1022 | Shape* shape = _shape->LevelAlpha(forceLOD); |
| 1023 | if (!shape) |
| 1024 | shape = _shape->LevelOpaque(forceLOD), alpha = false; |
| 1025 | #else |
| 1026 | Shape* shape = _shape->LevelOpaque(forceLOD); |
| 1027 | #endif |
| 1028 | PoseidonAssert(shape->NFaces() == 1); |
| 1029 | |
| 1030 | // many object are not fogged at all |
| 1031 | // disable fog calculation for them |
| 1032 | int special = shape->Special() | GetObjSpecial(); |
| 1033 | |
| 1034 | const Camera& camera = *GScene->GetCamera(); |
| 1035 | |
| 1036 | // following line is faster version |
| 1037 | Vector3 posp = GScene->ScaledInvTransform() * pos.Position(); |
| 1038 | |
| 1039 | // camera plane clip test |
| 1040 | // perform more distant clipping than normal |
| 1041 | float nearest = camera.Near() * 10; |
| 1042 | if (posp.Z() < nearest) |
| 1043 | { |
| 1044 | return; |
| 1045 | } |
| 1046 | |
| 1047 | float size = Scale(); |
| 1048 | |
| 1049 | Animate(forceLOD); |
| 1050 | |
| 1051 | // scale and 1/scale is kept in Frame |
| 1052 | |
| 1053 | // apply perspective on position and size |
| 1054 | Matrix4Val project = camera.Projection(); |
| 1055 | |
| 1056 | float invW = 1 / posp[2]; |
| 1057 | posp[0] = project(0, 2) + project(0, 0) * posp[0] * invW; |
| 1058 | posp[1] = project(1, 2) + project(1, 1) * posp[1] * invW; |
| 1059 | float nearPos = floatMax(posp[2] - size, nearest); |
| 1060 | float invNearPos = 1 / nearPos; |
| 1061 | posp[2] = project(2, 2) + project.Position()[2] * invNearPos; |
| 1062 | float rhw = invNearPos; |
| 1063 | |
| 1064 | // perspective screen size |
| 1065 | float sizeX = +project(0, 0) * size * invW * camera.InvLeft() * 0.5; |
| 1066 | float sizeY = -project(1, 1) * size * invW * camera.InvTop() * 0.5; |
| 1067 | |
| 1068 | if (sizeX * sizeY >= 0.5) |
| 1069 | { |
| 1070 | // never draw too small objects |
no test coverage detected