الاستعلامات المكانية

الاستعلامات المكانية هي عمليات يمكنك من خلالها سؤال خدمة العرض عن بعد عن الكائنات الموجودة في منطقة ما. تستخدم الاستعلامات المكانية بشكل متكرر لتنفيذ التفاعلات، مثل معرفة الكائن الذي يشير إليه المستخدم.

يتم تقييم جميع الاستعلامات المكانية على الخادم. وبالتالي فهي عمليات غير متزامنة وستصل النتائج مع تأخير يعتمد على زمن انتقال الشبكة. نظرا لأن كل استعلام مكاني يولد حركة مرور الشبكة ، فاحرص على عدم القيام بالكثير في وقت واحد.

شبكات التصادم

يتم تشغيل الاستعلامات المكانية بواسطة محرك Havok Physics وتتطلب وجود شبكة تصادم مخصصة. بشكل افتراضي، يقوم تحويل النموذج بإنشاء شبكات تصادم. إذا كنت لا تحتاج إلى استعلامات مكانية على نموذج معقد، ففكر في تعطيل إنشاء شبكة التصادم في خيارات التحويل، حيث يكون لها تأثير بطرق متعددة:

  • سيستغرق تحويل النموذج وقتا أطول بكثير.
  • أحجام ملفات الطراز المحولة أكبر بشكل ملحوظ ، مما يؤثر على سرعة التنزيل.
  • أوقات تحميل وقت التشغيل أطول.
  • استهلاك ذاكرة وحدة المعالجة المركزية وقت التشغيل أعلى.
  • هناك نفقات عامة طفيفة لأداء وقت التشغيل لكل مثيل نموذج.

يلقي راي

يلقي الأشعة هو استعلام مكاني حيث يتحقق وقت التشغيل من الكائنات التي تتقاطع مع شعاع ، بدءا من موضع معين والإشارة إلى اتجاه معين. كتحسين ، يتم أيضا إعطاء مسافة شعاع قصوى ، لعدم البحث عن الأشياء البعيدة جدا.

async void CastRay(RenderingSession session)
{
    // trace a line from the origin into the +z direction, over 10 units of distance.
    RayCast rayCast = new RayCast(new Double3(0, 0, 0), new Double3(0, 0, 1), 10);

    // only return the closest hit
    rayCast.HitCollection = HitCollectionPolicy.ClosestHit;

    RayCastQueryResult result = await session.Connection.RayCastQueryAsync(rayCast);
    RayCastHit[] hits = result.Hits;
    if (hits.Length > 0)
    {
        var hitObject = hits[0].HitObject;
        var hitPosition = hits[0].HitPosition;
        var hitNormal = hits[0].HitNormal;

        // do something with the hit information
    }
}
void CastRay(ApiHandle<RenderingSession> session)
{
    // trace a line from the origin into the +z direction, over 10 units of distance.
    RayCast rayCast;
    rayCast.StartPos = {0, 0, 0};
    rayCast.EndPos = {0, 0, 10};

    // only return the closest hit
    rayCast.HitCollection = HitCollectionPolicy::ClosestHit;

    session->Connection()->RayCastQueryAsync(rayCast, [](Status status, ApiHandle<RayCastQueryResult> result)
    {
        if (status == Status::OK)
        {
            std::vector<RayCastHit> hits;
            result->GetHits(hits);

            if (hits.size() > 0)
            {
                auto hitObject = hits[0].HitObject;
                auto hitPosition = hits[0].HitPosition;
                auto hitNormal = hits[0].HitNormal;

                // do something with the hit information
            }
        }
    });
}

هناك ثلاثة أوضاع لجمع النتائج:

  • Closest في هذا الوضع، سيتم الإبلاغ عن أقرب نتيجة فقط.:
  • Any تفضل هذا الوضع عندما يكون كل ما تريد معرفته هو ما إذا كان الشعاع سيصيب أي شيء ، ولكن لا تهتم بما تم ضربه بالضبط.: يمكن أن يكون هذا الاستعلام أرخص بكثير في التقييم ، ولكن أيضا يحتوي على عدد قليل من التطبيقات.
  • All في هذا الوضع ، يتم الإبلاغ عن جميع الضربات على طول الشعاع ، مرتبة حسب المسافة.: لا تستخدم هذا الوضع إلا إذا كنت بحاجة حقا إلى أكثر من الضربة الأولى. الحد من عدد الزيارات المبلغ عنها باستخدام الخيار MaxHits .

لاستبعاد الكائنات بشكل انتقائي من النظر في قوالب الأشعة، يمكن استخدام المكون HierarchicalStateOverrideComponent (HierarchicalStateOverrideComponent HierarchicalStateOverrideT

نتيجة الضرب

نتيجة استعلام إرسال الأشعة هي مجموعة من النتائج. الصفيف فارغ ، إذا لم يتم ضرب أي كائن.

يحتوي Hit على الخصائص التالية:

  • أي كيان أصيب.:HitEntity
  • SubPartId أي شبكة فرعية أصيبت في مكون شبكة.: يمكن استخدامها للفهرسة MeshComponent.UsedMaterials والبحث عن المواد في تلك المرحلة.
  • HitPosition موقع الفضاء العالمي حيث تقاطع الشعاع مع الجسم.:
  • HitNormal سطح الفضاء العالمي طبيعي للشبكة عند موضع التقاطع.:
  • DistanceToHit المسافة من موضع بدء الشعاع إلى الضربة.:

⁧⁩مستندات API⁧⁩.

الخطوات التالية