هذه المقالة محمية ضمن الحقوق الفكرية لشركة In|Framez Technology Corp.، ومرخصة للعرض فقط ضمن الشبكة العربية لمطوري الألعاب مع الموافقة الصريحة من المؤلف وشركة In|Framez Technology Corp.. لا يسمح بإعادة نشر هذه المقالة أو تعديلها دون الرجوع للمؤلف. يمنع النسخ والاقتباس دون ذكر المصدر والموافقة من المؤلف.
حسناً...سأكون صريحاً من البداية... قد يعاني قراء المقالة لهذا العدد من مشكلة غريبة نوعاً ما... تتلخص في كون هذه المقالة تتناول أساسيات ومبادئ بسيطة لموضوع متقدم في حد ذاته... فشريحة القراء الموجهة لهم هذه المقالة لم تعد واضحة، هل هي موجهة للمبتدئين أم للمحترفين؟ لذلك أرجو من أخواني المحترفين أن يعذورني في حال واجهوا بعض المعلومات البديهية كما على أعزائي المبتدأين أن يصبروا على الهجوم المكثف للمعلومات التقنية المتقدمة... وأعدكم أن أحاول تفادي هذا الأمر في المرات القادمة إن شاء الله... لنبدأ...
ماهي الـ MEL ولمحة سريعة على الأنظمة المشابهة... (للمبتدأين فقط!)
الـ MEL ببساطة هي النسخة المختصرة من العبارة المتحذلقة Maya Embedded Language أو بالعربي "لغة البرمجة المضمنة للـ Maya". بالطبع هذه ليست الترجمة الحرفية ولكنها قريبة نوعاً من مكافئتها الانجليزية والتي تساعدنا في معرفة السر وراء هذه الثلاثة أحرف. فنحن هنا نتحدث إذن عن نظام أو لغة برمجة مبسطة (scripting system) ضمن برنامج الـ Maya لبرمجة أو تطوير ميزات جديدة في البرنامج أو لأتمتة مجموعة من المهام الروتينية. بالطبع هذه الموضة منتشرة في معظم برامج الـ 3D الرئيسية. فمثلاً في الـ 3Ds MAX لدينا ما يسمى الـ MAX Script الذي يوفر لنا بيئة شبيهة بالـ MEL ولكنها أقل نضوجاً ومرونة نظراً لكونها لا تعتمد على نظام قياسي لصيغة الكتابة (Syntax) كما في الـ MEL التي تعتمد على صيغة شبيهة بالـ C أو الـ Java.
بقي لدينا الحديث عن النظام الخاص بالـ XSI... حيث لا يمكننا الحديث عن أنظمة الـ Scripting ومرونتها هنا دون ذكر ما يقدمه لنا الـ XSI، فهو في هذا المجال يعتبر من أكثر الأنظمة نضوجاً واحترافية حيث يوفر لنا معمارية رائعة للوصول والتحكم بالبرنامج من خلال طبقتان برمجيتان (Object Model Layer, Command Layer) إضافة لتوفيره وجهات تطوير خاصة (Tools Development Environment) تجعله أقرب لبيئات التطوير الاحترافية مثل Visual Studio وغيرها... ليس هذا وحسب... فبالنسبة للـ syntax أو صيغة البرمجة فهو يوفر لنا أكثر الأنظمة قياسية ومرونة من خلال اعتماده أكثر من لغة برمجة مثل VB Script، Java Script، Python الأمر الذي يعتبر ثورة في هذا المجال حيث لم يعد يحتاج المبرمج لتعلم لغة برمجة جديدة خاصة بالبرنامج بل يكفي أن يختار لغة البرمجة التي يتقنها ليبدأ بالعمل!
ولكن مهلاً لماذا كل هذا الاهتمام والتسهيلات في هذا المجال بالذات... هل نحن بحاجة فعلاً لكل هذه الميزات؟؟؟
لماذا نحن بحاجة لأنظمة scripting؟... (للمبتدأين أيضاً!)
معظم الذين أعرفهم يعملون في مجال الـ 3D يعتبرون التعامل مع أنظمة الـ scripting ضرباً من ضروب السحر الأسود الذي يستحق من يمارسه الحرق حياً. فأنت تجلس أمام شاشة الكمبيوتر لتكتب مجموع طويلة من الطلاسم والرموز الغريبة لتحصل في النهاية على نتيجة غريبة خارج حدود المنطق والعقل. لحسن الحظ تمكنت من تغيير هذه النظرة بالنسبة لأصدقائي في العمل من خلال اطلاعهم على ما أقوم به لاتحول من ساحر يستحق الحرق الى متحذلق يستحق الركل!... وهي بالطبع أفضل بكثير من جثة متفحمة... ولكن مهلاً... فما لبثت أن أريتهم نتائج هذه الشعوذة حتى أصبحت المخلص أو المنقذ بالنسبة لهم... حيث أصبح كل منهم يريدني أن أطور له أداة لتسرع عمله أو لتحل له مشكلة ما... وما أكثر المشاكل التي نواجهها أثناء عملنا! عندها أحس معظم هؤلاء بأهمية الـ scripting كنظام سحري لحل المشاكل وأحسست أنا بأهمية أن يكون النظام ناضج ومرن ليسهل لي مهمة التطوير والبرمجة...
الآن بالنسبة للقراء قد يكون إقناعهم بأهمية الأمر أصعب قليلاً لكونهم لم يجربوا التعامل مع مثل هذه الأنظمة من قبل ولكني سأكتفي بالمثال العملي الذي سوف ننفذه الآن للتعرف على ماذا يمكن أن تقدمه لنا مثل هذه الأنظمة.
مثال عملي (للمحترفين...)
دعونا نأخذ مثال على أحد المهمات الروتينية التي يمكن أن يساعدنا فيها وجود script لتنفيذها... لنفترض أنه طلب منا يوماً ما بناء مجموعة مختلفة من الأدراج بمواصفات خاصة لكل منها... فمثلاً لأحد الأبنية نحن بحاجة لدرج مؤلف من 30 درجة بارتفاع 25cm وآخر مؤلف من 14 درجة بارتفاع 75cm وهكذا...
بالطبع يمكننا بناءها جميعاً بشكل يدوي ولكن تخيل كم ستكون الحياة جميلة إذا كان لديك في الـ Maya أمر جديد تحدد له عدد الدرجات وارتفاع الدرجة وغيرها من المعلومات الاضافية ليقوم ببناءها لك بكبسة زر واحدة! حسناً... دعونا نبدأ بتطوير Script صغير ليقوم بهذه العملية...
لسهولة الشرح سنقوم ببناء الدرجات كصناديق منفصلة مرصوفة بجوار بعضها البعض لتشكيل الدرج المطلوب.
لبناء صندوق من خلال الـ Scripting نحن بحاجة لادخال الأمر التالي في الجزء السفلي من نافذة الـ Script Editor:
polyCube -w 1 -h 1 -d 1 -n “myFirstCube”;
قم الآن بتنفيذ هذا الأمر وذلك باختيار السطر الذي أدخلته واستخدام أمر التفيذ (Execute) من القائمة (Script) أو استخدام الاختصار (Ctrl+Enter).
إذا كان عملك صحيح ستجد مكعب جديد في مركز العالم... أبعاده 1 في كل الاتجاهات وأسمه "myFirstCube"...
بالطبع يمكنك تغيير أي من هذه الخصائص أو غيرها ببساطة استبدال القيمة التي تريدها أمام الرمز المقابل لها...
فمثلاً إذا كنا نريد جعل ارتفاعه 3.5 بدلاً من 1 فكل ما علينا هو وضع القيمة الجديدة 3.5 بعد الرمز –h والذي يرمز لارتفاع المكعب... فيصبح الأمر كالتالي...
polyCube -w 1 -h 3.5 -d 1 -n “myFirstCube”;
لمعرفة معاني هذه الرموز أو الخصائص الأخرى لهذا الأمر أو غيره لا مفر لديك من الاستعانة بالمراجع الالكترونية الخاصة بالـ MEL فهي تعتبر المرجع الوحيد اوالأفضل من حيث التتظيم وسهولة الوصول للمعلومة لهذا الغرض...
فمن غير المعقول أن تحفظ آلاف الأوامر للتمكن من البرمجة أو تضع بجانبك كتاب أسطوري يحوي مئات الصفحات التي تحتاج المزيد من الزمن للوصول للأمر المطلوب.
الآن وبعد أن تمكنا من انشاء مكعب والتحكم بخصائصه دعونا نحاول الأمر التالي لتحديد موقعه في الفراغ بدل من تركه يظهر في مركز العالم...
الآن إذا نفذت الأمرين السابقين ستحصل على مكعب بالمواصفات السابقة متوضع على الاحداثيات (0,3,4) بدلاً من مركز العالم... الفضل لتحديد الموقع بالطبع يعود للأمر move الذي يمكننا من تحديد احداثيات رقمية لتحديد مواقع الأجسام في المشهد.
حسناً... الى الآن لم نقم بالقيم بأي شيء يذكر... كل ما قمنا به هو انشاء مكعب بريء وتحديد مكانه في الفراغ... الآن لانشاء الدرج المطلوب نحن بحاجة للتعرف على بعض المفاهيم البرمجية البسيطة كالحلقات والمتغيرات...
المتغيرات variables والحلقات loops (للمحترفين فوق سن 18!)
لن أتعمق في موضوع المتغيرات هنا فهو بطبيعته سهل ومفهوم للجميع ولا يحمل أي من التعقيدات البرمجية في الـ mel كما في C/C++... فلتعريف أي متغير في الـ mel يكفي أن تحدد أسم المتغير مسبوقاً بالعلامة $ ونوعه ومنتهياً بالعلامة ; كما في الـ C/C++ أو الـ Java.
فمثلاً للتعريف عن المتغير x المنتمي لحقل الأعداد الحقيقية يكفي كتابة السطر التالي:
بعد الإعلان عن المتغير يمكننا تخزين أي قيمة فيه ولكن بالبطبع من نفس نوع المتغير المحدد... فلا يمكننا مثلاً الإعلان عن متغير من integer الخاص بتخزين الأعداد الصحيحة وتخزين ضمنه قيمة تنتمي للأعداد الحقيقية.
مثال على الإعلان عن متغير واسناد قيمة له:
float $myV;
$myV = 3.14556;
أو يمكننا للاختصار الاعلان عن المتغير واسناد قيمة له مباشرة كما في المثال التالي:
وإذا أردت المزيد من الاختصار يكفي فقط تحديد أسم المتغير والقيمة المسندة دون الحاجة لتحديد نوع المتغير حيث تقوم الـ mel بشيء من الذكاء وذلك لاستنتاج نوع المتغير المطلوب من طبيعة القيم المسندة...
واضح أن قيمة المتغير h تنتمي لحقل الأعداد الحقيقية لذلك ستقوم الـ mel بشكل تلقائي من حجز هذا المتغير بنوع float دون أن نصدع رؤوسنا بأنواع المتغيرات وكل هذه الروتينات المملة.
على ذكر الملل... بقي علينا أن نتعرف على مفهوم أساسي وبسيط في عالم البرمجة قبل أن تصابوا بالملل... الحلقات التكرارية أو loops...
في جميع لغات البرمجة وبلا استثناء أساليب مختلفة لتنفيذ كتل من الأوامر عدد محدد من المرات... سنتعرف في الـ mel على أحد هذه الأساليب الشهيرة وهي حلقات الـ for أو for loops...
الآن آلية عمل هذه الحلقات بسيط جداً... كل ما علينا هو تحديد عداد متزايد أو متناقص بين عددين صحيحين وتحديد الكتلة البرمجية المراد تكرارها...مثال:
for (عداد متزايد بين الواحد والـ 100 مثلاً)
{
كتلة برمجية مراد تكرارها...
}
دعونا نجرب مثال تطبيقي في الـ mel على هذه الحلقة التكرارية...سنقوم بكتابة برنامج يطبع لنا الأرقام من واحد الى 10...
for ($i = 0; $i <= 10; $i++)
{
print ($i+"...\n");
}
عمل جيد... الآن إذا كان عملك صحيح ستلاحظ أنه في الجزء العلوي من النافذة قامت الـ mel بطباعة الأعداد من 1 الى 10.
أعرف أنه ليس اختراع جديد وأن الجميع يعرف العد من الواحد للعشرة منذ كان في الثالثة من عمره ولكنها بالنسبة لمثالنا السابق أمر ضروري لا يمكننا اتمام العمل بدونهل... دعنا نرى ذلك…
تتمة المثال (ليس لأحد!):
لنتفرض الآن أننا نريد من البرنامج التدريبي انشاء درج مؤلف بناء 113 درجة! طبعاً من غير المعقول كتابة أومر البناء والتحريك لكل درجة على حدى! سنتسخدم الحلقات بالطبع!
سنقوم كما تعلمنا منذ قليل من انشاء حلقة تكرارية بعدد الدرجات المطلوبة…
for ($i = 0; $i <= 113; $i++)
{
}
علينا الآن إضافة أوامر البناء والتحريك ضمن الحلقة ليتم انشاء الدرجات المطلوبة... ولكن انتبه كيف سيتم استخدم المتغير المتزايد i لإزاحة الدرجات في الفراغ...
for ($i = 0; $i <= 113; $i++)
{
polyCube -w 3 -h 0.5 -d 1 -n " myFirstCube";
move -a 0 ($i*0.5) $i ;
}
قم بتنفيذ البرنامج واستمتع بالدرج الهائل الذي سينشئه هذا البريمج الصغير!
لاحظ كيف أن مقدار الإزاحة على المحور y في الأمر move يتم حسابه من خلال ضرب القيمة العددية المتزايدة في المتغير i بقيمة ارتفاع الدرجة المطلوب. بالطبع نفس الفكرة بالنسبة للمحور z.
الآن سنحاول استخدام المتغيرات لحفظ قيم خصائص الدرج لتسيهل التعامل مع البرنامج...
// user inputs...
$stHeight = .5;
$stWidth = 5;
$stDepth = 2.5;
$stCount = 12;
for ($i = 0; $i < $stCount; $i++)
{
$name = "stair"+$i;
$stY = $stHeight*$i;
$stZ = $stDepth*$i;
polyCube -w $stWidth -h $stHeight -d $stDepth -n $name;
move -a 0 $stY $stZ ;
}
حسناً هذه النسخة المطورة من البرنامج تمكننا من تحديد موصفات الدرج المطلوب في مجموعة المتغيرات في البداية دون الحاجة للخوض في تفاصيل الأوامر المستخدمة...
حاول أن تجرب قيم مختلفة لهذه المتغيرات وراقب كيف تنعكس نتائجها على الدرج الناتج.
الخاتمة (للجميع):
أعلم أني تجاوزت عدد الصفحات المخصصة لهذه المقالة وأعلم أني لم أنهي البرنامج كما ينبغي فما زال لدينا بناء واجهة الاستخدام واضافة حالات أخرى لمعالجة الأدراج الدائرية واضافة درابزينات وعشرات الميزات الإضافية التي لم نذكرها...
ولكن لا أريد أحد أن يلومني... فالموضوع كما لاحظ الجميع بسيط وممتع ولكنه متشعب وطويل لا يمكن تغطيته ببضع وريقات في مجلة... لذلك ضمن هذه الظروف يكفيني أن أكون قد تمكنت من تسليط الضوء على الأفكار الرئيسية للـ scripting في برامج الـ 3D بشكل عام و زرعت بعض الشجاعة عند مستخدمي الـ Maya للإقدام ومحاولة التعامل مع الـ mel... أما إحتراف البرمجة من خلال مقالة صغيرة فأعتقد أنه أمر صعب جداً ولكني سأحاول أن أكتب له script لتحقيقه... أدعوا لي بالتوفيق!...