مرکزی مواد پر جائیں
اے آئی ٹیوٹوریلز

Three.js میں طریقہ کار سے متحرک جانور بنائیں

جانیں کہ Procedural Animals کیسے انسٹال کریں، سیڈ شدہ جانور کیسے بنائیں، حرکت اور اعمال کو کیسے کنٹرول کریں، ایونٹس کیسے سنبھالیں، ورکرز کو کیسے ترتیب دیں، تیز لوڈنگ کے لیے اثاثے کیسے بیک کریں، اور سنیماٹک کلوز اَپس سے لے کر بڑے ہجوم تک مختلف استعمالات کے لیے معیار کی ترتیبات کیسے منتخب کریں۔

Three.js میں طریقہ کار سے متحرک جانور بنائیں

three.js Procedural Animals کیا ہے؟

three.js Procedural Animals ایک لائبریری ہے جس میں three.js کے لیے رن ٹائم پر تیار ہونے والے 24 جانور شامل ہیں۔ ماڈلز، ٹیکسچرز، رِگز یا اینیمیشن کلپس ڈاؤن لوڈ کرنے کے بجائے آپ createAnimal() کال کرتے ہیں، اور لائبریری کوڈ میں ایک مکمل متحرک جانور تیار کر دیتی ہے۔

ہر جانور کو سائنڈ ڈسٹنس فیلڈز سے تشکیل دیا جاتا ہے، پھر اس کا میش، رِگ اور اسکن تیار کیے جاتے ہیں، اسے فر، پروں یا چھلکوں سے ڈھانپا جاتا ہے، اور اِنورس کائنیمیٹکس کی چالوں اور حرکات کے ذریعے متحرک کیا جاتا ہے۔ دستیاب جسمانی ساختوں میں پنجوں والے جانور، کُھر والے جانور، پرندے، تیرنے والے جانور، سانپ، مکڑیاں اور اچھلنے والے جانور شامل ہیں۔

آپ ہر نوع، قسم، حرکت اور ڈیبگ ویو کو لائیو شوکیس میں دیکھ سکتے ہیں، یا GitHub ریپوزٹری میں سورس کا جائزہ لے سکتے ہیں۔

اہم خصوصیات

  • 24 انواع: اختیارات میں بھیڑیے، بلیاں، گھوڑے اور خرگوش سے لے کر پرندے، مچھلیاں، سانپ اور مکڑیاں شامل ہیں۔
  • Seed والے انفرادی جانور: جب تک آپ انہیں تبدیل نہ کریں، ایک seed سائز، تناسب، کوٹ، جنس، عمر اور قسم کے انتخاب کو قابلِ تکرار بناتا ہے۔
  • رن ٹائم اینیمیشن: جانور خودکار طور پر مناسب چالوں کا انتخاب کرتے ہیں اور بیٹھنے، سونے، کھانے، حملہ کرنے اور چھلانگ لگانے جیسی حرکات فراہم کرتے ہیں۔
  • پانچ معیار کی سطحیں: hero، high، medium، low اور crowd میں سے انتخاب کریں۔
  • ورکر پر مبنی تیاری: بلڈز پہلے سے طے شدہ طور پر ماڈیول Web Workers میں چلتی ہیں، اور کال کرنے والے تھریڈ پر واپس آنے کا متبادل بھی موجود ہے۔
  • آف لائن بیکنگ: کسی جانور کو .animal فائل کے طور پر پہلے سے تیار کریں تاکہ اسے تقریباً 20 ملی سیکنڈ میں لوڈ کیا جا سکے۔
  • گیم پر مبنی کنٹرولز: جانوروں کو چلائیں، انہیں منزلوں تک لے جائیں، فزکس باڈیز کی پیروی کرائیں، اہداف کا تعاقب کریں، حرکات چلائیں اور گیم پلے ایونٹس وصول کریں۔
  • TypeScript سپورٹ: پیکیج ES modules استعمال کرتا ہے اور TypeScript declarations شامل کرتا ہے۔

تنصیب

لائبریری کو اپنی واحد peer dependency کے طور پر three.js r160 یا بعد کا ورژن درکار ہے۔ npm کے ذریعے پیکیج اور three.js انسٹال کریں:

npm install procedural-animals three

اگر پیکیج ابھی npm پر دستیاب نہ ہو تو اسے براہِ راست GitHub سے انسٹال کریں:

npm install github:majidmanzarpour/threejs-procedural-animals three

اپنا پہلا جانور بنائیں

three.js اور createAnimal درآمد کرکے شروع کریں۔ یہ فنکشن غیر ہم زمانی ہے کیونکہ میش، رِگ، کورنگ اور متعلقہ ڈیٹا تیار کرنے میں وقت لگتا ہے۔

import * as THREE from 'three';
import { createAnimal } from 'procedural-animals';

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(innerWidth, innerHeight);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);

const scene = new THREE.Scene();
scene.background = new THREE.Color(0xa9c1e0);

const camera = new THREE.PerspectiveCamera(
  40,
  innerWidth / innerHeight,
  0.1,
  500
);
camera.position.set(6, 3, 8);

const sun = new THREE.DirectionalLight(0xfff3e4, 2.7);
sun.position.set(6, 10, 4);
sun.castShadow = true;

scene.add(
  sun,
  new THREE.HemisphereLight(0xdde6f2, 0x5f5a52, 1.15)
);

const floor = new THREE.Mesh(
  new THREE.PlaneGeometry(200, 200).rotateX(-Math.PI / 2),
  new THREE.MeshStandardMaterial({ color: 0x77736a })
);
floor.receiveShadow = true;
scene.add(floor);

async function main() {
  const wolf = await createAnimal('wolf', {
    seed: 3,
    quality: 'high'
  });

  scene.add(wolf.object);

  let last = performance.now();

  renderer.setAnimationLoop((now) => {
    const dt = (now - last) / 1000;
    last = now;

    wolf.move({
      speed: wolf.gears.walk,
      heading: now / 1000 * 0.3
    });

    wolf.update(dt);
    camera.lookAt(wolf.position);
    renderer.render(scene, camera);
  });
}

main();

اس مثال میں کئی اہم اصول ہیں:

  1. جانور کو async فنکشن کے اندر بنائیں اور نتیجے کے لیے await کریں۔
  2. animal.object کو scene میں شامل کریں، لیکن اس آبجیکٹ کی transform کو identity پر رکھیں۔ جانور اپنی حرکت خود سنبھالتا ہے۔
  3. اسے چلانے کے لیے move()، moveTo() یا follow() جیسے طریقے استعمال کریں۔
  4. ہر فریم میں update(dt) کو بالکل ایک بار کال کریں، جہاں dt سیکنڈز میں ناپا گیا ہو۔
  5. animal.gears سے رفتاریں استعمال کریں کیونکہ دستیاب gear نام نوع کے لحاظ سے مختلف ہو سکتے ہیں۔

انٹری ماڈیول میں top-level await استعمال کرنے سے گریز کریں۔ پروجیکٹ کی دستاویزات کے مطابق، یہ Vite کی production build کو deadlock کر سکتا ہے۔

حرکت اور نیویگیشن

براہِ راست اسٹیئرنگ

move() طریقہ میٹر فی سیکنڈ میں رفتار اور ریڈیئنز میں سمت لیتا ہے۔ 0 کی سمت مثبت Z محور کی طرف ہوتی ہے۔

wolf.move({
  speed: wolf.gears.walk,
  heading: Math.PI / 2
});

جب جانور کو حرکت روکنی ہو تو stop() کال کریں:

wolf.stop();

منزل تک حرکت

کسی جانور کو عالمی اسپیس کے نقطے کی طرف بھیجنے کے لیے moveTo() استعمال کریں۔ منزل تک پہنچنے کے بعد یہ arrive ایونٹ جاری کرتا ہے۔

wolf.moveTo(
  new THREE.Vector3(10, 0, 4),
  { speed: 3 }
);

wolf.on('arrive', () => {
  console.log('The wolf arrived.');
});

فزکس باڈی کی پیروی

اگر کسی دوسرے سسٹم کے ذریعے کوئی باڈی کنٹرول ہو رہی ہو تو ہر فریم اس کی موجودہ پوزیشن اور رفتار کو follow() میں دیں:

wolf.follow(body.position, body.velocity);

ہدف کا تعاقب

lookAt() کے ذریعے جانور کا سر کسی ہدف کی طرف موڑیں۔ تعاقب روکنے کے لیے null پاس کریں۔

wolf.lookAt(player.position);

// Later:
wolf.lookAt(null);

پلے ایکشنز

ہر نوع عام ایکشنز jump، sit، lie، sleep، eat، drink، attack، hit، death اور stand کو سپورٹ کرتی ہے۔ انواع خصوصی ایکشنز بھی فراہم کر سکتی ہیں۔ مثال کے طور پر، سانپ حلقہ بنا کر حملہ کر سکتے ہیں، پرندے اڑان بھر کر اتر سکتے ہیں، اور خرگوش اچھل اور زمین پر پاؤں مار سکتے ہیں۔

play() میتھڈ ایک Promise واپس کرتا ہے جس کا نتیجہ done، interrupted، stopped یا refused ہو سکتا ہے۔

const result = await wolf.play('attack');
console.log(result);

یہ فرض کرنے کے بجائے کہ کوئی نوع خصوصی ایکشن کو سپورٹ کرتی ہے، animal.actions کا معائنہ کریں۔ آپ stopAction() کے ذریعے کسی نامزد ایکشن کو روک سکتے ہیں:

wolf.stopAction('attack');

جانوروں کے ایونٹس کا جواب دیں

ایونٹ API گیم سسٹمز کو اینیمیشن اور حرکت پر ردعمل دینے کی سہولت فراہم کرتی ہے۔ دستیاب ایونٹس میں footstep، attackHit، actionStart، actionEnd، arrive، takeoff، land، death، vocalize اور wingbeat شامل ہیں۔

const onFootstep = (event) => {
  sfx.play('step', event.position, event.strength);
};

wolf.on('footstep', onFootstep);

wolf.on('attackHit', (event) => {
  damage(event.position, event.direction);
});

// Remove a listener when it is no longer needed.
wolf.off('footstep', onFootstep);

زمین اور پانی ترتیب دیں

ground آپشن ایک ایسا فنکشن ہے جو X اور Z کوآرڈینیٹ کے لیے زمین کی اونچائی واپس کرتا ہے۔ اس کے کوآرڈینیٹس animal.object.parent کی اسپیس میں ہونے چاہییں، اور واپس کی گئی اونچائی سین میں رینڈر کی گئی زمین سے مطابقت رکھنی چاہیے۔

const deer = await createAnimal('deer', {
  ground: (x, z) => terrainHeightAt(x, z),
  position: new THREE.Vector3(4, 0, 8),
  heading: Math.PI
});

تیرنے والے جانوروں کے لیے water فنکشن اور سطح سے نیچے ابتدائی پوزیشن درکار ہوتی ہے۔ یہ فنکشن پانی کی سطح کی اونچائی واپس کرتا ہے، یا جہاں پانی موجود نہ ہو وہاں null واپس کرتا ہے۔

const fish = await createAnimal('fish', {
  water: (x, z) => 2,
  position: new THREE.Vector3(0, 1, 0)
});

scene.add(fish.object);

خشکی کے جانور پینے اور پانی میں چلنے کے لیے پانی کی تعریف بھی استعمال کر سکتے ہیں۔ پرندوں کو perches کی ایک array دی جا سکتی ہے جس میں THREE.Vector3 پوائنٹس شامل ہوں جہاں وہ اڑ کر جا سکتے ہیں۔

انواع، اقسام اور انفرادی جانور منتخب کریں

لائبریری میں بھیڑیے، کتے، لومڑیاں، بلیاں، شیر، چیتے، ریچھ، چوہے، خرگوش، گھوڑے، ہرن، گائیں، سور، بھیڑیں، بکریاں، جنگلی سور، مینڈک، مرغیاں، کوے، عقاب، مچھلیاں، شارک، سانپ اور مکڑیاں شامل ہیں۔

قابلِ تکرار انفرادی جانور بنانے کے لیے seed استعمال کریں۔ آپ اس کی قسم، جنس یا عمر بھی واضح طور پر منتخب کر سکتے ہیں:

const cat = await createAnimal('cat', {
  seed: 12,
  quality: 'high',
  variant: 'tuxedo',
  sex: 'female',
  age: 'adult'
});

اسٹرنگ کی صورت میں دیے گئے نوع کے شناخت کنندگان ضرورت کے وقت لوڈ ہوتے ہیں۔ اگر کسی ایپلیکیشن کو صرف ایک نوع درکار ہو تو بنڈل کو مرکوز رکھنے کے لیے اس نوع کو براہِ راست امپورٹ کریں:

import wolfSpecies from 'procedural-animals/species/wolf';
import { createAnimal } from 'procedural-animals';

const wolf = await createAnimal(wolfSpecies, {
  seed: 3
});

درست کوالٹی درجۂ منتخب کریں

  • hero: تقریباً 110,000 سے 130,000 vertices، سنیماٹک کلوز اپس کے لیے۔
  • high: تقریباً 65,000 سے 80,000 vertices، کھلاڑی کے جانور کے لیے۔ یہ طے شدہ اختیار ہے۔
  • medium: تقریباً 25,000 سے 32,000 vertices، درمیانے فاصلے کے مناظر اور فونز کے لیے۔
  • low: تقریباً 11,000 سے 15,000 vertices، تقریباً 10 سے 20 جانوروں کے ریوڑ کے لیے۔
  • crowd: تقریباً 5,000 سے 8,000 vertices، تقریباً 100 جانوروں کے ہجوم کے لیے، ایک draw call کے ساتھ۔

آپ setQuality() کے ذریعے موجودہ mesh کی کوٹ کی تفصیل تبدیل کر سکتے ہیں۔ بڑے ہجوم کے لیے crowd درجے کو setLod(2) کے ساتھ استعمال کریں تاکہ حرکت کی تفصیل کم ہو جائے:

const sheep = await createAnimal('sheep', {
  seed: 5,
  quality: 'crowd'
});

sheep.setLod(2);

Build کے نتائج نوع، seed، کوالٹی اور variant کے لحاظ سے cache کیے جاتے ہیں۔ اس لیے چھ seeds استعمال کرنے والے 100 جانوروں کے ریوڑ کے لیے صرف چھ منفرد builds درکار ہوتے ہیں۔ دستاویزی CPU لاگت فی فریم فی جانور تقریباً 0.1 milliseconds ہے۔

Web Workers ترتیب دیں

جانوروں کی builds میں تقریباً 0.4 سے 6 seconds لگتے ہیں۔ طے شدہ طور پر construction ماڈیول Web Workers میں چلتی ہے۔ اگر Worker دستیاب نہ ہو تو لائبریری calling thread پر واپس آ جاتی ہے۔

Vite کنفیگریشن

// vite.config.js
export default {
  worker: { format: 'es' },
  build: { target: 'es2022' },
  optimizeDeps: {
    exclude: ['procedural-animals']
  }
};

webpack 5 اور Parcel 2 کے لیے اضافی worker کنفیگریشن درکار نہیں۔

دیگر Bundlers

کسی دوسرے bundler کے لیے worker کو دستی طور پر bundle کریں:

npx esbuild node_modules/procedural-animals/src/worker.js --bundle --format=iife --minify --outfile=public/animal-worker.js

پھر ایسا factory رجسٹر کریں جو worker بنائے:

import { setWorkerFactory } from 'procedural-animals';

setWorkerFactory(
  () => new Worker('/animal-worker.js')
);

آپ کسی مخصوص جانور کے لیے worker construction کو غیر فعال کر سکتے ہیں، لیکن اس صورت میں build کے پورے دورانیے تک calling thread رک جائے گی:

const wolf = await createAnimal('wolf', {
  worker: false
});

تیز لوڈنگ کے لیے جانوروں کو پہلے سے تیار کریں

کسی معروف فرد کے لیے اسے پہلے ہی ایک .animal فائل میں تیار کر لیں۔ اس سے رن ٹائم کی تعمیر میں لگنے والی تاخیر ختم ہو جاتی ہے اور اس کی جگہ فائل لوڈ ہوتی ہے، جس کے بارے میں README تقریباً 20 ملی سیکنڈ کا تخمینہ دیتا ہے۔

npx procedural-animals-bake wolf --seed 3 --quality high -o public/wolf-3.animal

تیار کردہ فائل کو ArrayBuffer کے طور پر حاصل کریں اور اسے baked آپشن کے ذریعے فراہم کریں:

const wolf = await createAnimal('wolf', {
  baked: fetch('/wolf-3.animal')
    .then((response) => response.arrayBuffer())
});

تیار کردہ فرد اسی نوع اور کنفیگریشن کے مطابق ہونا چاہیے جو کمانڈ کے ذریعے تیار کی گئی تھی۔

اعلیٰ درجے کی تجاویز

صرف پڑھنے کے لیے حرکت کی حالت استعمال کریں

کیمراؤں، گیم پلے یا انٹرفیس کو مربوط کرنے کے لیے position، heading، speed، velocity اور state پڑھیں۔ حرکت پیدا کرنے کے لیے جانور کے روٹ آبجیکٹ میں براہِ راست تبدیلی نہ کریں۔

پراپس کو نام زدہ نقاط سے منسلک کریں

attachments مجموعہ mouth، head اور back جیسے نقاط فراہم کرتا ہے۔ پرندوں میں پاؤں کے اٹیچمنٹس بھی دستیاب ہوتے ہیں، جبکہ گھوڑوں میں سواری سے متعلق نقاط شامل ہیں، جن میں seat، رکابیں اور لگام کے حصے شامل ہیں۔ پراپس کو ان اٹیچمنٹ آبجیکٹس کا چائلڈ بنائیں، بجائے اس کے کہ ان کی متحرک پوزیشن کا دستی تخمینہ لگائیں۔

ڈیبگ اور کورنگ کنٹرولز استعمال کریں

جانور کی API میں setDebug(mode, on) شامل ہے، جس کے موڈز albedo، weights، material اور bare ہیں۔ فر شیلز کو ٹوگل کرنے کے لیے setCoverings(on) استعمال کریں۔

wolf.setDebug('weights', true);
wolf.setCoverings(false);

کسی نقطے کی طرف رخ کا حساب لگائیں

چونکہ ہیڈنگ صفر مثبت Z کی سمت ہوتی ہے، اس لیے ہدف کی سمت کا حساب لگاتے وقت Math.atan2(dx, dz) استعمال کریں:

const dx = target.x - wolf.position.x;
const dz = target.z - wolf.position.z;
const heading = Math.atan2(dx, dz);

wolf.move({
  speed: wolf.gears.walk,
  heading
});

وسائل صاف کریں

جب کسی جانور کو مستقل طور پر ہٹا دیا جائے تو dispose() کال کریں۔ اس سے اس کے GPU وسائل آزاد ہو جاتے ہیں اور وہ منظر سے ہٹ جاتا ہے۔

wolf.dispose();

مفید ایکسپورٹس اور دستاویزات

مرکزی پیکیج listSpecies، loadSpecies، setWorkerFactory، clearBuildCache اور QUALITY بھی ایکسپورٹ کرتا ہے:

import {
  createAnimal,
  listSpecies,
  loadSpecies,
  setWorkerFactory,
  clearBuildCache,
  QUALITY
} from 'procedural-animals';

ہر آپشن، ایونٹ پے لوڈ، حالت کے فیلڈ اور ترکیب کے لیے ریپوزٹری کے مکمل حوالہ اور TypeScript اعلانات سے رجوع کریں۔

نتیجہ

three.js Procedural Animals، three.js ایپلیکیشن میں متنوع، رِگ شدہ اور متحرک جنگلی حیات شامل کرنے کا کوڈ پر مبنی طریقہ فراہم کرتا ہے۔ createAnimal() سے آغاز کریں، واپس ملنے والے آبجیکٹ کو منظر میں شامل کریں، جانور کی API کے ذریعے اسے ہدایت دیں اور ہر فریم میں ایک بار اسے اپ ڈیٹ کریں۔ ورکرز، بیکنگ، سیڈ شدہ کیشنگ اور متعدد کوالٹی درجات ایک ہی ورک فلو کو تفصیلی قریبی مناظر اور بڑے ہجوم، دونوں کے لیے موزوں بناتے ہیں۔