⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 3dengine.cpp

📁 一个三维打斗游戏
💻 CPP
字号:
// (C) Copyright 1996 by Anthony J. Carin.  All Rights Reserved.
#include <stdafx.h>
#include "3dengine.h"
#include <stdlib.h>
#include "scrlsurf.h"
#include "3dtools.h"
#include "command.h"

view camera;

const   short BUFSIZE    = 500;
const   uchar COLORDIFF  = 10;

image::image(LPCTSTR filename, direction ydir)
{
   readfile(filename);
   m_size = 1.0f;
   color = RGB(255,255,255);
   m_yoff = ydir;
}

image::~image()
{
   for (int i = 0; i < numsurfs; i++)
   {
       delete m_surfs[i];
       delete m_mysurfs[i];
   }
   delete [] m_points;
   delete [] m_surfs;
   delete [] m_mysurfs;
}

void  image::setbmpsurf(short index, CString& face)
{
    if (index < 0 ||
        index >= numsurfs ||
        Game->Detail() < 7)
        return;
    delete m_mysurfs[index];
    m_mysurfs[index] = new bmpsurf(face);
    ((bmpsurf *)m_mysurfs[index])->ExemptFromIntersect();
}

void  image::readfile(LPCTSTR filename)
{
   char buf[BUFSIZE];
   fptr = fopen(filename, "r");
   if (fptr > 0)
   {
        getsize(buf);
        getpoints(buf);
        getsurfaces(buf);
        buf[0] = 0;
        fgets(buf, BUFSIZE, fptr);
        if (buf[0] != 0)
            findend(buf);
        m_genstring = buf;
        fclose(fptr);
   }
}

void  image::getsize(char *buf)
{
   char *ptr;
   fgets(buf, BUFSIZE, fptr);
   ptr = findend(buf);
   findend(ptr);
   numpoints  = (short)atoi(buf);
   numsurfs   = (short)atoi(ptr);
   m_points   = new point[numpoints];
   m_surfs    = (surfs **) new char[numsurfs*sizeof(surfs *)];
   m_mysurfs  = (surfs **) new char[numsurfs*sizeof(surfs *)];
   for (short i = 0; i < numsurfs; i++)
   {
       m_surfs[i] = new surfs();
       m_mysurfs[i] = new surfs();
   }
}

void  image::getpoints(char *buf)
{
   char *ptr1, *ptr2;
   for (short i = 0; i < numpoints; i++)
   {
      fgets(buf, BUFSIZE, fptr);
      ptr1 = findend(buf);
      ptr2 = findend(ptr1);
      findend(ptr2);
      m_points[i].setto(convertfloat(buf), -convertfloat(ptr1), convertfloat(ptr2));
   }
}

void  image::getsurfaces(char *buf)
{
   char type;
   char *ptr1, *ptr2, *ptr3, *ptr4, *ptr5;
   short p1,p2,p3,p4 = 0;
   CString p5;
   for (short i = 0; i < numsurfs; i++)
   {
      fgets(buf, BUFSIZE, fptr);
      type = (char)atoi(buf);
      ptr1 = findend(buf);
      p1   = (short)(atoi(ptr1) - 1);
      ptr2 = findend(ptr1);
      p2   = (short)(atoi(ptr2) - 1);
      ptr3 = findend(ptr2);
      p3   = (short)(atoi(ptr3) - 1);
      ptr4 = findend(ptr3);
      if (type >= 4 && type <= 6)
      {
          p4 = (short)(atoi(ptr4) - 1);
          ptr5 = findend(ptr4);
          if (type == 5 || type == 6)
          {
              int numbmps = multiplesurfs(ptr5);
              if (numbmps > 1)
              {
                  delete m_mysurfs[i];
                  scrollsurf *sptr = new scrollsurf();
                  while (numbmps--)
                  {
                      ptr4 = findend(ptr5);
                      p5 = (CString) ptr5;
                      sptr->addsurf(p5);
                      ptr5 = ptr4;
                  }
                  m_mysurfs[i] = sptr;
                  if (type == 6)
                     ((bmpsurf *) m_mysurfs[i])->ExemptFromIntersect();
              }
              else
              {
                  findend(ptr5);
                  p5 = (CString) ptr5;
                  delete m_mysurfs[i];
                  m_mysurfs[i] = new bmpsurf(p5);
                  if (type == 6)
                     ((bmpsurf *) m_mysurfs[i])->ExemptFromIntersect();
              }
          }
      }
      if (type == 3)
          m_surfs[i]->setto(m_points[p1], m_points[p2], m_points[p3]);
      else
          m_surfs[i]->setto(m_points[p1], m_points[p2], m_points[p3], m_points[p4]);
      m_surfs[i]->CalcNormals();
   }
}

char * image::findend(char *ptr)
{
   while (*ptr != ' ' && *ptr != '\n')
      ptr++;
   *ptr++ = 0;
   return ptr;
}

int image::multiplesurfs(char *ptr)
{
   int num = 1;
   char spaces = FALSE;
   while (*ptr != '\0' && *ptr != '\n')
   {
      if (*ptr == ' ' || *ptr == '\t')
          spaces = TRUE;
      if (*ptr != ' ' && *ptr != '\t' && spaces == TRUE)
      {
          spaces = FALSE;
          num++;
      }
      ptr++;
   }
   return num;
}

void  image::draw()
{
    if (outofrange())
        return;
    copysurfs();

    Game->Tool3d()->material(color);

    if (Game->Detail() < 10)
    {
        for (short i = 0; i < numsurfs; i++)
            if (m_mysurfs[i]->IsABmp() || random((short)((int)Game->Detail()+2)) != 1)
                m_mysurfs[i]->draw();
    }
    else
    {
        for (short i = 0; i < numsurfs; i++)
            m_mysurfs[i]->draw();
    }
}

char image::outofrange()
{
    xdirfromcamera = camera.xdirectionto(m_view);
    ydirfromcamera = camera.ydirectionto(m_view);
    direction xdir = xdirfromcamera - camera.xdirection();
    direction ydir = ydirfromcamera - camera.ydirection();

    if (camera.distanceto(m_view) > VIEWRANGE)
        return TRUE;
    if (ydir > (direction) TC_PI && ydir < (direction) -TC_PI)
        return TRUE;
    if (xdir > (direction) TC_PI && xdir < (direction) -TC_PI)
        return TRUE;
    return FALSE;
}

void image::OnlySurfExemptFromIntersect()
{
    if (numsurfs > 0)
    {
        if (m_mysurfs[0]->IsABmp())
            ((bmpsurf *)m_mysurfs[0])->ExemptFromIntersect();
    }
}

surfs * image::OnlySurf()
{
    if (numsurfs > 0)
        return m_mysurfs[0];
    return (surfs *) 0;
}

void image::copysurfs()
{
    for (short i = 0; i < numsurfs; i++)
    {
        *m_mysurfs[i] = *m_surfs[i];
        m_mysurfs[i]->xrotate(m_view.xdirection());
        m_mysurfs[i]->zrotate(m_view.zdirection());
        m_mysurfs[i]->yrotate(m_view.ydirection()+m_yoff);
        *m_mysurfs[i] += m_view;
    }
}

void surfs::operator =(surfs& s)
{
   NormalX      = s.NormalX;
   NormalY      = s.NormalY;
   NormalZ      = s.NormalZ;
   polygon::operator =(s);
}

void surfs::xrotate(direction& d)
{
   if (!d.iszero())
   {
       m_a.xrotate(d);
       m_b.xrotate(d);
       m_c.xrotate(d);
       m_d.xrotate(d);
   }
}

void surfs::yrotate(direction& d)
{
   if (!d.iszero())
   {
       m_a.yrotate(d);
       m_b.yrotate(d);
       m_c.yrotate(d);
       m_d.yrotate(d);
   }
}

void surfs::zrotate(direction& d)
{
   if (!d.iszero())
   {
       m_a.zrotate(d);
       m_b.zrotate(d);
       m_c.zrotate(d);
       m_d.zrotate(d);
   }
}

void surfs::operator +=(coordinate& c)
{
   m_a += c;
   m_b += c;
   m_c += c;
   m_d += c;
}

void surfs::draw()
{
    if (m_linenum == 3)
    {
        Game->Tool3d()->begintriangle();
        Game->Tool3d()->normals(NormalX, NormalY, NormalZ);
        Game->Tool3d()->vertex(m_a.x(), m_a.y(), m_a.z());
        Game->Tool3d()->vertex(m_b.x(), m_b.y(), m_b.z());
        Game->Tool3d()->vertex(m_c.x(), m_c.y(), m_c.z());
        Game->Tool3d()->end();
    }
    else
    {
        Game->Tool3d()->beginquad();
        Game->Tool3d()->normals(NormalX, NormalY, NormalZ);
        Game->Tool3d()->vertex(m_a.x(), m_a.y(), m_a.z());
        Game->Tool3d()->vertex(m_b.x(), m_b.y(), m_b.z());
        Game->Tool3d()->vertex(m_c.x(), m_c.y(), m_c.z());
        Game->Tool3d()->vertex(m_d.x(), m_d.y(), m_d.z());
        Game->Tool3d()->end();
    }
}


void surfs::CalcNormals()
{
    coordinate a,b;
    a = m_b - m_a;
    b = m_c - m_a;
    NormalX = a.y() * b.z() - a.z() * b.y();
    NormalY = a.z() * b.x() - a.x() * b.z();
    NormalZ = a.x() * b.y() - a.y() * b.x();
    float length = (float)sqrt(NormalX*NormalX+NormalY*NormalY+NormalZ*NormalZ);
    if (length != 0)
    {
        NormalX /= length;
        NormalY /= length;
        NormalZ /= length;
    }
}

char surfs::iswithin(coordinate& c)
{
    if (m_linenum == 0)
        return FALSE;
    if (m_c.x() == m_b.x())
    {
        if (m_c.z() < m_b.z())
        {
            if (c.z() < m_c.z() ||  c.z() > m_b.z())
                return FALSE;
        }
        else
        {
            if (c.z() < m_b.z() ||  c.z() > m_c.z())
                return FALSE;
        }
        if (m_c.x() < m_d.x())
        {
            if (c.x() < m_c.x() ||  c.x() > m_d.x())
                return FALSE;
        }
        else
        {
            if (c.x() < m_d.x() ||  c.x() > m_c.x())
                return FALSE;
        }
    }
    else
    {
        if (m_c.z() < m_d.z())
        {
            if (c.z() < m_c.z() ||  c.z() > m_d.z())
                return FALSE;
        }
        else
        {
            if (c.z() < m_d.z() ||  c.z() > m_c.z())
                return FALSE;
        }
        if (m_c.x() < m_b.x())
        {
            if (c.x() < m_c.x() ||  c.x() > m_b.x())
                return FALSE;
        }
        else
        {
            if (c.x() < m_b.x() ||  c.x() > m_c.x())
                return FALSE;
        }
    }
    return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -