<!-- SAGA2 · part 103 -->
){ return new THREE.Vector3(p.x+ox, p.y+oy, p.z); });
      sentinelGrp.add(new THREE.Line(new THREE.BufferGeometry().setFromPoints(ptw), mat));
    }
  }
  // CORE — sphere of contour lines
  for(var i=0; i<16; i++){
    var pts=[], lat = -1.2+i*0.15;
    for(var j=0;j<=24;j++){ var an=j/24*Math.PI*2;
      var r = 4*Math.cos(lat);
      pts.push(new THREE.Vector3(Math.cos(an)*r, Math.sin(lat)*4, Math.sin(an)*r));
    }
    sdraw(pts, i%4===0?sGold:sCyan);
  }
  // ORBIT RINGS — 3 gyroscope rings
  [[0,0,0],[Math.PI/3,0,0],[0,0,Math.PI/3]].forEach(function(rot, idx){
    var pts=[];
    for(var j=0;j<=40;j++){ var an=j/40*Math.PI*2;
      var x = Math.cos(an)*7, y = Math.sin(an)*7, z = 0;
      // rotate
      var x2 = x, y2 = y*Math.cos(rot[0])-z*Math.sin(rot[0]), z2 = y*Math.sin(rot[0])+z*Math.cos(rot[0]);
      pts.push(new THREE.Vector3(x2, y2, z2));
    }
    sdraw(pts, idx===0?sGold:sCyan);
  });
  // SINGLE EYE — central
  var eye = new THREE.Mesh(new THREE.SphereGeometry(0.8, 12, 12),
    new THREE.MeshBasicMaterial({color:0x44ffaa}));
  eye.position.set(0, 0, 3.5);
  sentinelGrp.add(eye);
}


var scoutGrp = null;
function buildScout(){
  if(scoutGrp) return;
  scoutGrp = new THREE.Group();
  scoutGrp.position.set(0, 0, -50);
  scoutGrp.scale.set(0.5, 0.5, 0.5);
  scene.add(scoutGrp);
  var eGreen = new THREE.LineBasicMaterial({color:0x44ff88, transparent:true, opacity:0.7, blending:THREE.AdditiveBlending});
  var eSilver = new THREE.LineBasicMaterial({color:0xcccccc, transparent:true, opacity:0.9, blending:THREE.AdditiveBlending});
  var eDim = new THREE.LineBasicMaterial({color:0x226644, transparent:true, opacity:0.5, blending:THREE.AdditiveBlending});
  function edraw(pts, mat){
    for(var w=0; w<8; w++){
      var ox=(Math.random()-0.5)*0.25, oy=(Math.random()-0.5)*0.25;
      var ptw = pts.map(function(p){ return new THREE.Vector3(p.x+ox, p.y+oy, p.z); });
      scoutGrp.add(new THREE.Line(new THREE.BufferGeometry().setFromPoints(ptw), mat));
    }
  }
  // HEAD — smooth oval (not dome)
  for(var h=0; h<14; h++){
    var pts=[], hy = 22-h*0.9;
    for(var j=0;j<=20;j++){ var an=j/20*Math.PI*2;
      var hr = 4.2*Math.sin(Math.PI*(h/14));
      if(hr<0.5) hr=0.5;
      pts.push(new THREE.Vector3(Math.cos(an)*hr, hy, 2+Math.sin(an)*hr*0.9));
    }
    edraw(pts, h%5===0?eSilver:eGreen);
  }
  // EYES — emerald
  [-1.6,1.6].forEach(function(ex){
    var eye = new THREE.Mesh(new THREE.SphereGeometry(0.5, 10, 10),
      new THREE.MeshBasicMaterial({color:0x44ff88}));
    eye.position.set(ex, 19, 6.2);
    scoutGrp.add(eye);
  });
  // NECK — slim
  for(var n=0; n<10; n++){
    var pts=[], na=n/10*Math.PI*2;
    for(var ny=0; ny<=5; ny++) pts.push(new THREE.Vector3(Math.cos(na)*2.2, 14-ny*1.0, Math.sin(na)*2.2));
    edraw(pts, eDim);
  }
  // TORSO — slim tapered
  for(var t=0; t<16; t++){
    var pts=[], ty = 12-t*0.9, tr = 6.5-t*0.25;
    for(var j=0;j<=20;j++){ var an=j/20*Math.PI*2;
      pts.push(new THREE.Vector3(Math.cos(an)*tr, ty, Math.sin(an)*tr*0.7));
    }
    edraw(pts, t%5===0?eSilver:eGreen);
  }
  // ARMS — slim
  [-1,1].forEach(function(sd){
    var ax = sd*8;
    for(var a=0; a<14; a++){
      var pts=[], ay = 10-a*1.4;
      for(var j=0;j<=14;j++){ var an=j/14*Math.PI*2;
        pts.push(new THREE.Vector3(ax+Math.cos(an)*2.0, ay, 5+Math.sin(an)*1.8));
      }
      edraw(pts, a%5===0?eSilver:eGreen);
    }
  });
  // LEGS — slim
  [-1,1].forEach(function(sd){
    var lx = sd*3.5;
    for(var l=0; l<16; l++){
      var pts=[], ly = -2-l*1.6;
      for(var j=0;j<=14;j++){ var an=j/14*Math.PI*2;
        pts.push(new THREE.Vector3(lx+Math.cos(an)*2.4, ly, Math.sin(an)*2.0));
      }
      edraw(pts, l%5===0?eSilver:eGreen);
    }
  });
}


var humanGrp = null;
function buildHuman(){
  if(humanGrp) return;
  humanGrp = new THREE.Group();
  humanGrp.position.set(0, 0, 0);
  humanGrp.scale.set(0.5, 0.5, 0.5);
  scene.add(humanGrp);
  var hWarm = new THREE.LineBasicMaterial({color:0xffddaa, transparent:true, opacity:0.75, blending:THREE.AdditiveBlending});
  var hSoft = new THREE.LineBasicMaterial({color:0xddbb99, transparent:true, opacity:0.6, blending:THREE.AdditiveBlending});
  var hDim = new THREE.LineBasicMaterial({color:0x886655, transparent:true, opacity:0.5, blending:THREE.AdditiveBlending});
  function hdraw(pts, mat){
    for(var w=0; w<8; w++){
      var ox=(Math.random()-0.5)*0.2, oy=(Math.random()-0.5)*0.2;
      var ptw = pts.map(function(p){ return new THREE.Vector3(p.x+ox, p.y+oy, p.z); });
      humanGrp.add(new THREE.Line(new THREE.BufferGeometry().setFromPoints(ptw), mat));
    }
  }
  for(var h=0; h<16; h++){
    var pts=[], hy = 24-h*1.0, hr = 4.5*Math.sin(Math.PI*(0.15+0.7*h/16));
    if(hr<0.8) hr=0.8;
    for(var j=0;j<=22;j++){ var an=j/22*Math.PI*2;
      pts.push(new THREE.Vector3(Math.cos(an)*hr, hy, 1.5+Math.sin(an)*hr*0.92));
    }
    hdraw(pts, h%5===0?hWarm:hSoft);
  }
  [-1.7,1.7].forEach(function(ex){
    for(var er=0; er<3;