Package com.ngt.jopenmetaverse.shared.sim

Source Code of com.ngt.jopenmetaverse.shared.sim.TerrainManager

/**
* A library to interact with Virtual Worlds such as OpenSim
* Copyright (C) 2012  Jitendra Chauhan, Email: jitendra.chauhan@gmail.com
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License,
* or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.ngt.jopenmetaverse.shared.sim;

import java.util.Observable;

import com.ngt.jopenmetaverse.shared.protocol.BitPack;
import com.ngt.jopenmetaverse.shared.protocol.LayerDataPacket;
import com.ngt.jopenmetaverse.shared.protocol.PacketType;
import com.ngt.jopenmetaverse.shared.sim.TerrainCompressor.TerrainPatch;
import com.ngt.jopenmetaverse.shared.sim.events.EventObservable;
import com.ngt.jopenmetaverse.shared.sim.events.EventObserver;
import com.ngt.jopenmetaverse.shared.sim.events.PacketReceivedEventArgs;
import com.ngt.jopenmetaverse.shared.sim.events.terrain.LandPatchReceivedEventArgs;
import com.ngt.jopenmetaverse.shared.types.Vector2;
import com.ngt.jopenmetaverse.shared.util.JLogger;
import com.ngt.jopenmetaverse.shared.util.Utils;

public class TerrainManager
  /// <summary>Raises the LandPatchReceived event</summary>
  /// <param name="e">A LandPatchReceivedEventArgs object containing the
  /// data returned from the simulator</param>
  private EventObservable<LandPatchReceivedEventArgs> onLandPatchReceived = new EventObservable<LandPatchReceivedEventArgs>();
  public void registerOnLandPatchReceived(EventObserver<LandPatchReceivedEventArgs> o)
  {
    onLandPatchReceived.addObserver(o);
  }
  public void unregisterOnLandPatchReceived(EventObserver<LandPatchReceivedEventArgs> o)
  {
    onLandPatchReceived.deleteObserver(o);
  }
 
//    //region EventHandling
//      /// <summary>The event subscribers. null if no subcribers</summary>
//      private EventHandler<LandPatchReceivedEventArgs> m_LandPatchReceivedEvent;
//
//      /// <summary>Raises the LandPatchReceived event</summary>
//      /// <param name="e">A LandPatchReceivedEventArgs object containing the
//      /// data returned from the simulator</param>
//      protected virtual void OnLandPatchReceived(LandPatchReceivedEventArgs e)
//      {
//          EventHandler<LandPatchReceivedEventArgs> handler = m_LandPatchReceivedEvent;
//          if (handler != null)
//              handler(this, e);
//      }
//
//      /// <summary>Thread sync lock object</summary>
//      private readonly object m_LandPatchReceivedLock = new object();
//
//      /// <summary>Raised when the simulator responds sends </summary>
//      public event EventHandler<LandPatchReceivedEventArgs> LandPatchReceived
//      {
//          add { lock (m_LandPatchReceivedLock) { m_LandPatchReceivedEvent += value; } }
//          remove { lock (m_LandPatchReceivedLock) { m_LandPatchReceivedEvent -= value; } }
//      }
//      //endregion

      private GridClient Client;

      /// <summary>
      /// Default constructor
      /// </summary>
      /// <param name="client"></param>
      public TerrainManager(GridClient client)
      {
          Client = client;
//          Client.network.RegisterCallback(PacketType.LayerData, LayerDataHandler);
          Client.network.RegisterCallback(PacketType.LayerData, new EventObserver<PacketReceivedEventArgs>(){
      @Override
      public void handleEvent(Observable o, PacketReceivedEventArgs arg) {
        LayerDataHandler(o, arg);
      }
          });

      }
           
     
//      private void printIntArray(int[] array)
//      {
//       int count = 0;
//       while(count < array.length)
//       {
//         System.out.println("");
//         for(int x =0 ; x < 50 && count <  array.length   ; x++)
//         {
//           System.out.print((int)array[count++] + " ");
//         }
//       }
//     }
     
      private void DecompressLand(Simulator simulator, BitPack bitpack, TerrainPatch.GroupHeader group)
      {
          int x;
          int y;
          int[] patches = new int[32 * 32];
          int count = 0;

          while (true)
          {
              TerrainPatch.Header header = TerrainCompressor.DecodePatchHeader(bitpack);

              if (header.QuantWBits == TerrainCompressor.END_OF_PATCHES)
                  break;

              x = header.getX();
              y = header.getY();

              if (x >= TerrainCompressor.PATCHES_PER_EDGE || y >= TerrainCompressor.PATCHES_PER_EDGE)
              {
                  JLogger.warn(String.format(
                      "Invalid LayerData land packet, x=%d, y=%d, dc_offset=%f, range=%d, quant_wbits=%d, patchids=%d, count=%d",
                      x, y, header.DCOffset, header.Range, header.QuantWBits, header.PatchIDs, count));
                  return;
              }

              // Decode this patch
              TerrainCompressor.DecodePatch(patches, bitpack, header, group.PatchSize);

              //TODO only for debugging
//              System.out.println("Decoded Patch: ");
//              printIntArray(patches);
             
              // Decompress this patch
              float[] heightmap = TerrainCompressor.DecompressPatch(patches, header, group);

              count++;

              if (Client.settings.STORE_LAND_PATCHES)
              {
                  TerrainPatch patch = new TerrainPatch();
                  patch.Data = heightmap;
                  patch.X = x;
                  patch.Y = y;
                  simulator.Terrain[y * 16 + x] = patch;
              }
             
              try { onLandPatchReceived.raiseEvent(new LandPatchReceivedEventArgs(simulator, x, y, group.PatchSize, heightmap)); }
              catch (Exception e) { JLogger.error(Utils.getExceptionStackTraceAsString(e)); }

          }
      }

      private void DecompressWind(Simulator simulator, BitPack bitpack, TerrainPatch.GroupHeader group)
      {
          int[] patches = new int[32 * 32];

          // Ignore the simulator stride value
          group.Stride = group.PatchSize;

          // Each wind packet contains the wind speeds and direction for the entire simulator
          // stored as two float arrays. The first array is the X value of the wind speed at
          // each 16x16m block, second is the Y value.
          // wind_speed = distance(x,y to 0,0)
          // wind_direction = vec2(x,y)

          // X values
          TerrainPatch.Header header = TerrainCompressor.DecodePatchHeader(bitpack);
          TerrainCompressor.DecodePatch(patches, bitpack, header, group.PatchSize);
          float[] xvalues = TerrainCompressor.DecompressPatch(patches, header, group);

          // Y values
          header = TerrainCompressor.DecodePatchHeader(bitpack);
          TerrainCompressor.DecodePatch(patches, bitpack, header, group.PatchSize);
          float[] yvalues = TerrainCompressor.DecompressPatch(patches, header, group);

          if (simulator.Client.settings.STORE_LAND_PATCHES)
          {
              for (int i = 0; i < 256; i++)
                  simulator.WindSpeeds[i] = new Vector2(xvalues[i], yvalues[i]);
          }
      }

      private void DecompressCloud(Simulator simulator, BitPack bitpack, TerrainPatch.GroupHeader group)
      {
          // FIXME:
          JLogger.warn("DecompressCloud not implemented");
      }

      private void LayerDataHandler(Object sender, PacketReceivedEventArgs e)
      {
          LayerDataPacket layer = (LayerDataPacket)e.getPacket();
          BitPack bitpack = new BitPack(layer.LayerData.Data, 0);
          TerrainPatch.GroupHeader header = new TerrainPatch.GroupHeader();
          TerrainPatch.LayerType type = TerrainPatch.LayerType.get(layer.LayerID.Type);

          // Stride
          header.Stride = bitpack.UnpackBits(16);
          // Patch size
          header.PatchSize = bitpack.UnpackBits(8);
          // Layer type
          header.Type = TerrainPatch.LayerType.get((byte)bitpack.UnpackBits(8));

          switch (type)
          {
              case Land:
                  if (onLandPatchReceived != null || Client.settings.STORE_LAND_PATCHES)
                      DecompressLand(e.getSimulator(), bitpack, header);
                  break;
              case Water:
                  JLogger.error("Got a Water LayerData packet, implement me!");
                  break;
              case Wind:
                  DecompressWind(e.getSimulator(), bitpack, header);
                  break;
              case Cloud:
                  DecompressCloud(e.getSimulator(), bitpack, header);
                  break;
              default:
                  JLogger.warn("Unrecognized LayerData type " + type.toString());
                  break;
          }
      }
  }
TOP

Related Classes of com.ngt.jopenmetaverse.shared.sim.TerrainManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.