Example #1
0
        public float Sample(Vector2D coord)
        {
            if (coord.X > 1)
                coord.X = 1;
            else if (coord.X < 0)
                coord.X = 0;
            if (coord.Y > 1)
                coord.Y = 1;
            else if (coord.Y < 0)
                coord.Y = 0;

            return SampleActual((int)(coord.X * (width - 1)), (int)(coord.Y * (height - 1)));
        }
        public HeightFieldObject(Vector3D origin, MaterialShader shader, Vector2D size, Bitmap bitmapSrc)
            : base(origin, shader, -1)
        {
            this.bitmapSrc = bitmapSrc;
            // calculate bounds
            areaExtent = size;
            Vector2D halfSize = size * 0.5;
            areaStart = origin - halfSize;
            areaEnd = origin + halfSize;
            double szLen = size.Length();
            radius = Math.Sqrt((szLen * szLen) + (1.1 * 1.1)) / 2;

            hField = HeightField.FromBitmap(bitmapSrc);

            onePx = new Vector2D(areaExtent.X / hField.Width, areaExtent.Y / hField.Height);

            this.origin.Y = 0.5;

            zMin = 0;
            zTop = 1;

            rectangles = new Rectangle3D[]
            {
                new Rectangle3D(new Vector3D(areaStart.X, zTop, areaStart.Y), new Vector3D(areaEnd.X, zTop, areaEnd.Y),
                                new PlaneD(new Vector3D(0, 1, 0), -zTop)),           // top
                new Rectangle3D(new Vector3D(areaStart.X, zMin, areaStart.Y), new Vector3D(areaEnd.X, zMin, areaEnd.Y),
                                new PlaneD(new Vector3D(0, -1, 0), zMin)),          // bottom
                new Rectangle3D(new Vector3D(areaStart.X, zMin, areaStart.Y), new Vector3D(areaStart.X, zTop, areaEnd.Y), 
                                new PlaneD(new Vector3D(-1, 0, 0), halfSize.X)),    // left
                new Rectangle3D(new Vector3D(areaEnd.X, zMin, areaStart.Y), new Vector3D(areaEnd.X, zTop, areaEnd.Y),
                                new PlaneD(new Vector3D(1, 0, 0), -halfSize.X)),     // right
                new Rectangle3D(new Vector3D(areaStart.X, zMin, areaStart.Y), new Vector3D(areaEnd.X, zTop, areaStart.Y),
                                new PlaneD(new Vector3D(0, 0, -1), halfSize.Y)),    // front 
                new Rectangle3D(new Vector3D(areaStart.X, zMin, areaEnd.Y), new Vector3D(areaEnd.X, zTop, areaEnd.Y),
                                new PlaneD(new Vector3D(0, 0, 1), -halfSize.Y)),     // back
            };
        }
 public override Vector2D GetTexCoord(Vector3D p, uint subIdx)
 {
     Vector2D coord = new Vector2D(p.X - areaStart.X, p.Z - areaStart.Y);
     coord.X /= areaExtent.X;
     coord.Y /= areaExtent.Y;
     return coord;
 }
        public override Vector3D GetNormal(Vector3D pos, uint subIdx)
        {
            Vector2D coord = new Vector2D(pos.X - areaStart.X, pos.Z - areaStart.Y);
            coord.X /= areaExtent.X;
            coord.Y /= areaExtent.Y;
            
            // calc normal from surrounding pixels
            float val = hField.Sample(coord);
            float valxmin = hField.SampleShiftX(coord.X, coord.Y, -1);
            float valxmax = hField.SampleShiftX(coord.X, coord.Y, 1);

            Vector3D rightAngle = new Vector3D(0, 0, -1);
            Vector3D p1 = new Vector3D(onePx.X, valxmax - val, 0).Cross(rightAngle);
            Vector3D p2 = new Vector3D(-onePx.X, valxmin - val, 0).Cross(rightAngle);
            Vector3D xDir = Vector3D.Normalize(p1 - p2);

            float valymin = hField.SampleShiftY(coord.X, coord.Y, -1);
            float valymax = hField.SampleShiftY(coord.X, coord.Y, 1);

            rightAngle = new Vector3D(1, 0, 0);
            p1 = new Vector3D(0, valymax - val, onePx.Y).Cross(rightAngle);
            p2 = new Vector3D(0, valymin - val, -onePx.Y).Cross(rightAngle);
            Vector3D yDir = Vector3D.Normalize(p1 - p2);
            
            return Vector3D.Normalize(xDir + yDir);
        }