যদি এই প্রশ্নে এটি আপনার প্রথমবার হয় তবে আমি প্রথমে নীচের প্রাক-আপডেট অংশটি পড়ার পরামর্শ দিচ্ছি, তারপরে এই অংশটি। সমস্যাটির সংশ্লেষণটি এখানে, যদিও:
মূলত, আমার একটি গ্রিড স্পেসিয়াল পার্টিশন সিস্টেমের সাথে সংঘর্ষ সনাক্তকরণ এবং রেজোলিউশন ইঞ্জিন রয়েছে যেখানে ক্রম-সংঘর্ষ এবং সংঘর্ষের গ্রুপগুলি বিবেচনা করে। একবারে একটির দেহ অবশ্যই চলতে হবে, তারপরে সংঘর্ষ সনাক্ত করতে হবে এবং তারপরে সংঘর্ষগুলি সমাধান করবে। যদি আমি একবারে সমস্ত দেহ সরিয়ে নিয়ে যাই, তবে সম্ভাব্য সংঘর্ষের জোড়া তৈরি করুন, এটি স্পষ্টতই দ্রুত, তবে রেজুলেশন ভেঙে গেছে কারণ ক্রম-সংঘর্ষকে সম্মান করা হচ্ছে না। যদি আমি একবারে একটি দেহ স্থানান্তরিত করি তবে আমি সংঘর্ষগুলি পরীক্ষা করতে লাশ পেতে বাধ্য হয়েছি এবং এটি একটি ^ 2 সমস্যা হয়ে দাঁড়িয়েছে। মিশ্রণগুলিতে গোষ্ঠীগুলি রাখুন এবং আপনি কল্পনা করতে পারেন যে এটি প্রচুর সংখ্যক দেহের সাথে খুব দ্রুত কেন খুব ধীর হয়।
আপডেট: আমি এটিতে সত্যিই কঠোর পরিশ্রম করেছি, তবে কিছুই অপ্টিমাইজ করার ব্যবস্থা করতে পারিনি।
আমি একটি বড় সমস্যাও আবিষ্কার করেছি : আমার ইঞ্জিনটি ক্রম-সংঘর্ষের উপর নির্ভরশীল।
আমি অনন্য সংঘর্ষের জুড়ি প্রজন্মের একটি বাস্তবায়নের চেষ্টা করেছি , যা স্পষ্টতই অনেক কিছু দিয়ে সমস্ত গতি বাড়িয়েছিল, তবে সংঘর্ষের অর্ডারকে ভেঙেছে ।
আমাকে ব্যাখ্যা করতে দাও:
আমার আসল নকশায় (জোড় তৈরি হচ্ছে না), এটি ঘটে:
- একটি শরীরের নড়াচড়া
- এটি সরানোর পরে, এটি তার কোষগুলিকে সতেজ করে এবং এতে যে দেহগুলির মুখোমুখি হয় সেগুলি তা পায়
- যদি এটি কোনও শরীরে ওভারল্যাপ করে তবে তার বিপরীতে সমাধান করা দরকার, সংঘর্ষের সমাধান করুন
এর অর্থ হ'ল যদি কোনও দেহ সরে যায় এবং একটি প্রাচীরের (বা অন্য কোনও দেহ) আঘাত করে তবে কেবল যে দেহটি স্থানান্তরিত হয়েছে তা তার সংঘর্ষের সমাধান করবে এবং অন্য দেহটি ক্ষতিগ্রস্থ হবে না।
এটিই আমার আচরণের ইচ্ছা ।
আমি বুঝতে পারি এটি পদার্থবিজ্ঞানের ইঞ্জিনগুলির পক্ষে সাধারণ নয়, তবে রেট্রো স্টাইলের গেমগুলির জন্য এর অনেক সুবিধা রয়েছে ।
সাধারণ গ্রিড ডিজাইনে (স্বতন্ত্র জোড় তৈরি করে) এটি ঘটে:
- সমস্ত দেহ সরানো
- সমস্ত দেহ সরে যাওয়ার পরে, সমস্ত কক্ষকে রিফ্রেশ করুন
- অনন্য সংঘর্ষের জোড়া উত্পাদন
- প্রতিটি জোড়া জন্য, সংঘর্ষ সনাক্তকরণ এবং রেজোলিউশন হ্যান্ডেল
এই ক্ষেত্রে একযোগে পদক্ষেপের ফলে দুটি দেহ ওভারল্যাপিং হতে পারে, এবং তারা একই সাথে সমাধান করবে - এটি কার্যকরভাবে দেহগুলিকে "একে অপরকে চারপাশে ঠেলে" তোলে এবং একাধিক সংস্থার সাথে সংঘর্ষের স্থায়িত্বকে ভেঙে দেয়
এই আচরণটি পদার্থবিজ্ঞানের ইঞ্জিনগুলির জন্য সাধারণ, তবে এটি আমার ক্ষেত্রে গ্রহণযোগ্য নয় ।
আমি আরও একটি সমস্যা পেয়েছি, যা প্রধান (যদিও এটি বাস্তব-বিশ্বের পরিস্থিতিতে হওয়ার সম্ভাবনা না থাকলেও):
- A, B এবং W গ্রুপের সংস্থাগুলি বিবেচনা করুন
- একটি সংঘর্ষে ডাব্লু এবং এ এর বিপরীতে সমাধান হয়
- বি সংঘর্ষে ডব্লিউ এবং বি এর বিপরীতে সমাধান করে
- এ বি এর বিরুদ্ধে কিছুই করে না
- খ ক এর বিপরীতে কিছুই করে না
এমন পরিস্থিতি তৈরি হতে পারে যেখানে প্রচুর এ সংস্থা এবং বি সংস্থা একই কোষ দখল করে থাকে - সেক্ষেত্রে মৃতদেহের মধ্যে প্রচুর অপ্রয়োজনীয় পুনরাবৃত্তি ঘটে যা একে অপরের সাথে প্রতিক্রিয়া প্রকাশ করে না (বা কেবল সংঘর্ষ সনাক্ত করে তবে সেগুলি সমাধান করে না) ।
একই কক্ষটি দখল করা 100 টি মৃতদেহের জন্য, এটি 100 ^ 100 পুনরাবৃত্তি! এটি ঘটে কারণ অনন্য যুগগুলি উত্পন্ন হচ্ছে না - তবে আমি অনন্য জোড়া তৈরি করতে পারি না , অন্যথায় আমি এমন আচরণ পেতে চাই যা আমি চাই না।
এই ধরণের সংঘর্ষ ইঞ্জিনকে অনুকূল করার কোনও উপায় আছে কি?
এই নির্দেশাবলী যে সম্মান করা আবশ্যক:
সংঘর্ষের ক্রমটি অত্যন্ত গুরুত্বপূর্ণ!
- দেহগুলিকে অবশ্যই একবারে একটি স্থানান্তরিত করতে হবে , তারপরে একবারে সংঘর্ষের জন্য পরীক্ষা করতে হবে এবং একবারে আন্দোলনের পরে সমাধান করতে হবে ।
দেহগুলিতে 3 টি গ্রুপ বিটসেট থাকতে হবে
- গোষ্ঠী : দলগুলি শরীরের অন্তর্ভুক্ত
- গ্রুপসটেক : শরীরের বিরুদ্ধে গ্রুপের সংঘর্ষ সনাক্ত করতে হবে groups
- গোষ্ঠী নো রিসলভ : গ্রুপের সাথে শরীরের সংঘর্ষের সমাধান করা উচিত নয়
- এমন পরিস্থিতি থাকতে পারে যেখানে আমি কেবল একটি সংঘর্ষ সনাক্ত করতে পারি তবে সমাধান হয় নি
প্রি-আপডেট:
মূলশব্দ : আমি সচেতন যে এই বাধাটি অনুকূলকরণ কোনও প্রয়োজনীয়তা নয় - ইঞ্জিনটি ইতিমধ্যে খুব দ্রুত। আমি যাইহোক, মজা এবং শিক্ষামূলক উদ্দেশ্যে, ইঞ্জিনটিকে আরও দ্রুততর করার কোনও উপায় খুঁজে পেতে পছন্দ করব।
আমি নমনীয়তা এবং গতির উপর জোর দিয়ে একটি সাধারণ-উদ্দেশ্য সি ++ 2 ডি সংঘর্ষ সনাক্তকরণ / প্রতিক্রিয়া ইঞ্জিন তৈরি করছি।
এখানে এর স্থাপত্যের একটি খুব প্রাথমিক চিত্র রয়েছে:
মূলত, প্রধান শ্রেণিটি হ'ল World
, যা ক ResolverBase*
, ক SpatialBase*
এবং ক এর মেমরি পরিচালনা করে vector<Body*>
।
SpatialBase
একটি খাঁটি ভার্চুয়াল ক্লাস যা ব্রড-ফেজ সংঘর্ষ সনাক্তকরণের সাথে সম্পর্কিত deals
ResolverBase
একটি খাঁটি ভার্চুয়াল ক্লাস যা সংঘর্ষের রেজোলিউশনের কাজ করে।
দেহগুলি বস্তুগুলির World::SpatialBase*
সাথে যোগাযোগ SpatialInfo
করে, দেহগুলির নিজস্ব মালিকানা।
সেখানে কৌতূহলীভাবে একটি স্থানিক শ্রেণি রয়েছে: Grid : SpatialBase
এটি একটি বেসিক ফিক্সড 2 ডি গ্রিড। এটির নিজস্ব তথ্য বর্গ রয়েছে GridInfo : SpatialInfo
,।
এটির স্থাপত্যটি কীভাবে দেখায় তা এখানে:
Grid
বর্গ একটি 2D অ্যারে মালিক Cell*
। Cell
বর্গ একটি সংগ্রহ (মালিকানাধীন নয়) রয়েছে Body*
: একটি vector<Body*>
যা সব মৃতদেহ যে কক্ষে রয়েছে।
GridInfo
বস্তুগুলির মধ্যে দেহটি যে কোষে থাকে সেগুলিতে অ-মালিকানাধীন পয়েন্টারও থাকে।
আমি আগেই বলেছি, ইঞ্জিনগুলি গ্রুপগুলির উপর ভিত্তি করে।
Body::getGroups()
একটি ফেরৎstd::bitset
সকল গোষ্ঠী শরীরের অংশ।Body::getGroupsToCheck()
std::bitset
শরীরের সাথে সংঘর্ষের জন্য চেক করতে থাকা সমস্ত গ্রুপের একটি ফেরত দেয় ।
দেহগুলি একক কোষের চেয়ে বেশি দখল করতে পারে। গ্রিডআইনফো সর্বদা দখলকৃত কক্ষগুলিতে অ-মালিকানার পয়েন্টার সঞ্চয় করে।
একটি একক শরীরের সরানোর পরে, সংঘর্ষ সনাক্তকরণ ঘটে। আমি ধরে নিলাম যে সমস্ত সংস্থা অক্ষ-সংযুক্ত বাউন্ডিং বাক্স।
ব্রড-ফেজ সংঘর্ষ সনাক্তকরণ কীভাবে কাজ করে:
পর্ব 1: স্থানিক তথ্য আপডেট
প্রত্যেকের জন্য Body
body
:
- শীর্ষ-বামদিকের অধিষ্ঠিত ঘর এবং নীচে-ডানদিকের অধিষ্ঠিত ঘরগুলি গণনা করা হয়।
- যদি সেগুলি পূর্ববর্তী কোষগুলির থেকে পৃথক হয়,
body.gridInfo.cells
পরিষ্কার হয়ে যায় এবং দেহটি দখল করে এমন সমস্ত কোষে পূর্ণ হয় (উপরের-বামতম কোষ থেকে নীচে-ডানদিকের কোষে লুপের জন্য 2 ডি)।
body
এটি কোষগুলি কী দখল করে তা এখন নিশ্চিতভাবে গ্যারান্টিযুক্ত।
পার্ট 2: প্রকৃত সংঘর্ষের চেক
প্রত্যেকের জন্য Body
body
:
body.gridInfo.handleCollisions
বলা হয়:
void GridInfo::handleCollisions(float mFrameTime)
{
static int paint{-1};
++paint;
for(const auto& c : cells)
for(const auto& b : c->getBodies())
{
if(b->paint == paint) continue;
base.handleCollision(mFrameTime, b);
b->paint = paint;
}
}
void Body::handleCollision(float mFrameTime, Body* mBody)
{
if(mBody == this || !mustCheck(*mBody) || !shape.isOverlapping(mBody->getShape())) return;
auto intersection(getMinIntersection(shape, mBody->getShape()));
onDetection({*mBody, mFrameTime, mBody->getUserData(), intersection});
mBody->onDetection({*this, mFrameTime, userData, -intersection});
if(!resolve || mustIgnoreResolution(*mBody)) return;
bodiesToResolve.push_back(mBody);
}
সংঘর্ষের পরে প্রতিটি শরীরের জন্য সমাধান করা হয়
bodiesToResolve
।এটাই.
সুতরাং, আমি বেশ কিছুক্ষণ ধরে এই ব্রড-ফেজ সংঘর্ষ সনাক্তকরণটিকে অনুকূলিত করার চেষ্টা করছি। আমি যখনই বর্তমান আর্কিটেকচার / সেটআপ ব্যতীত অন্য কিছু চেষ্টা করি, তখন পরিকল্পনা মতো কিছু হয় না বা পরে আমি যে সিমুলেশনটি মিথ্যা বলে প্রমাণিত হয় তা সম্পর্কে অনুমান করি।
আমার প্রশ্ন: আমি কীভাবে আমার সংঘর্ষের ইঞ্জিনের ব্রড-ফেজটি অনুকূল করতে পারি ?
এখানে কি কোনও ধরণের ম্যাজিক সি ++ অপ্টিমাইজেশন প্রয়োগ করা যেতে পারে?
আরও পারফরম্যান্সের অনুমতি দেওয়ার জন্য কি আর্কিটেকচারটি আবার ডিজাইন করা যেতে পারে?
- আসল বাস্তবায়ন: এসএসভিএসক্লশন
- বডি। , বডি কোড
- World.h , World.cpp
- গ্রিড.হ. , গ্রিড.কম
- সেল.হ. , সেল.ক.পি.
- গ্রিডআইনফো , গ্রিডআইএনফো। পিপি
সর্বশেষ সংস্করণটির জন্য কলগ্রিনড আউটপুট: http://txtup.co/rLJgz
getBodiesToCheck()
6৪6২৩৩৩ বার বলা হয়েছিল এবং পুরো প্রোফাইলিংয়ের 35,1% সময় নিয়েছিল (নির্দেশ পাঠের জন্য অ্যাক্সেসের সময়)