pos is used mainly for proper proxy object positioning. This is the main function used for object rendering. Default implementation performs Object::Animate before and Object::Deanimate after rendering, checks for fog optimization (early constant fog evaluation), selects lights that may influence this object, draws all proxies via Object::DrawProxies and draws the given LOD level via Shape::Draw.
| 835 | // evaluation), selects lights that may influence this object, draws all proxies via |
| 836 | // Object::DrawProxies and draws the given LOD level via Shape::Draw. |
| 837 | void Object::Draw(int forceLOD, ClipFlags clipFlags, const FrameBase& pos) |
| 838 | { |
| 839 | if (!_shape) |
| 840 | { |
| 841 | return; |
| 842 | } |
| 843 | |
| 844 | if (forceLOD == LOD_INVISIBLE) |
| 845 | { |
| 846 | return; // invisible LOD |
| 847 | } |
| 848 | |
| 849 | Shape* sShape = _shape->LevelOpaque(forceLOD); |
| 850 | if (sShape->NFaces() <= 0) |
| 851 | { |
| 852 | return; |
| 853 | } |
| 854 | |
| 855 | // test if reference points to valid object |
| 856 | // get object position in clipping coordinates |
| 857 | Animate(forceLOD); |
| 858 | |
| 859 | if (clipFlags) |
| 860 | { |
| 861 | // try to clip bounding sphere |
| 862 | Vector3 bCenter; |
| 863 | float bRadius; |
| 864 | AnimatedBSphere(forceLOD, bCenter, bRadius, true); |
| 865 | |
| 866 | // note: this we may be inside of proxy object |
| 867 | Vector3 bCenterW = pos.PositionModelToWorld(bCenter); |
| 868 | float bRadiusW = bRadius * Scale(); |
| 869 | const ClipFlags clipKeep = ClipUser0; |
| 870 | clipFlags &= GScene->GetCamera()->MayBeClipped(bCenterW, bRadiusW, 1) | clipKeep; |
| 871 | } |
| 872 | |
| 873 | PoseidonAssert(forceLOD >= 0); |
| 874 | |
| 875 | LightList work(true); |
| 876 | // many object are not fogged at all |
| 877 | // disable fog calculation for them |
| 878 | int special = sShape->Special() | GetObjSpecial(); |
| 879 | float dist2 = GScene->GetCamera()->Position().Distance2(pos.Position()); |
| 880 | |
| 881 | float constFog = -1; |
| 882 | bool skip = false; |
| 883 | { |
| 884 | const render::LegacySpec specT = render::SplitLegacy(special); |
| 885 | if (!render::Has(specT.routing, render::Routing::FogDisabled)) |
| 886 | { |
| 887 | float radius = pos.Scale() * _shape->BoundingSphere(); |
| 888 | if (NoFogNeeded(dist2, sShape, radius)) |
| 889 | { |
| 890 | special |= FogDisabled, constFog = 0; |
| 891 | } |
| 892 | else |
| 893 | { |
| 894 | constFog = ConstFogUsed(dist2, sShape, radius); |
no test coverage detected